Fonction utilisant une variable statique locale thread safe / reentrant

J’ai une fonction qui va générer un nombre aléatoire unique (essentiellement incrémenter précédent) à différents threads l’invoquant.

Ce fil est-il sûr ou est-ce reentrant? Supposons que j’utilise une variable statique pour ce nombre.

J’ai vu dans ce forum des variables statiques ne peuvent pas être utilisées pour reentrant / thread safe.

Cela s’applique-t-il aux statiques locales / globales?

Ou est-ce que l’implémentation est définie?

Changer un object “ordinaire” partagé entre les threads n’est jamais thread-safe, sauf si vous en prenez soin. (et toute variable déclarée statiquement entre dans cette catégorie). Il y a deux façons standard de traiter avec cela

  • utilisez un mutex ou une autre structure de verrou pour protéger l’object partagé à l’intérieur d’une “section critique”
  • utiliser des opérations atomiques pour accéder à l’object, le nouveau standard C, C11 a des interfaces pour cela

Être réentrant demande si une exécution (même sans threads) peut modifier une partie de l’état, par exemple la récursion, les gestionnaires de signaux ou les sauts avec goto ou longjmp . Voyez cela comme partageant une variable avec “vous-même”. Les variables allouées statiquement posent les mêmes problèmes ici, si vous les modifiez à des endroits différents du programme.

En C, les variables static locales sont initialisées de manière thread-safe car elles sont toujours initialisées au démarrage du programme, avant que des threads puissent être créés. Il n’est pas autorisé d’initialiser des variables static locales avec des valeurs non constantes précisément pour cette raison.

 void some_function(int arg) { // This initialization is thread-safe and reentrant, since it happens at // program startup static int my_static = 42; // ERROR: Initializer is not constant static int another_static = arg; ... } 

Bien sûr, que toute la fonction soit thread-safe ou réentrant dépend entièrement de la manière dont vous utilisez les variables statiques. Comme elles sont effectivement identiques aux variables globales, vous devez vous assurer d’utiliser les mutex appropriés lors de leur lecture ou de leur écriture (ou d’autres structures de synchronisation) afin de garantir la sécurité des threads.

Pour vous assurer que la fonction est réentrante, vous devez examiner avec soin quand et comment la fonction peut s’appeler elle-même (peut-être indirectement via une autre fonction) et vous assurer que tout l’état global se comporte de manière cohérente.