web-dev-qa-db-fra.com

Les variables statiques de fonction sont-elles thread-safe dans GCC?

Dans l'exemple de code

void foo()
{
  static Bar b;
  ...
}

compilé avec GCC est-il garanti que b sera créé et initialisé de manière thread-safe?

Dans la page de manuel de gcc, a trouvé l'option de ligne de commande - - fno-threadsafe-statics:

N'émettez pas le code supplémentaire pour utiliser les routines spécifiées dans le C++ ABI pour l'initialisation thread-safe des statiques locales. Vous pouvez utiliser cette option pour réduire légèrement la taille du code dans le code qui n'a pas besoin d'être thread-safe.

  1. Est-ce à dire que les statiques locales sont par défaut thread-safe avec GCC? Donc, aucune raison de mettre une garde explicite, par exemple avec pthread_mutex_lock/unlock?

  2. Comment écrire du code portable - comment vérifier si le compilateur ajoutera ses gardes? Ou est-il préférable de désactiver cette fonctionnalité de GCC?

58
CsTamas
  1. Non, cela signifie que le initialisation des statics locaux est thread-safe.

  2. Vous voulez vraiment laisser cette fonctionnalité activée. L'initialisation thread-safe des statics locaux est très importante. Si vous avez généralement besoin d'un accès thread-safe aux statics locaux, vous devrez ajouter les protecteurs appropriés vous-même.

42
CB Bailey

Nous avons eu de sérieux problèmes avec le code de verrouillage généré par GCC 3.4 pour protéger l'initialisation statique locale. Cette version utilisait un mutex partagé mondial pour protéger tout et toute initialisation statique qui conduisait à un blocage dans notre code. Nous avions une variable statique locale initialisée à partir du résultat d'une fonction, qui a démarré un autre thread, qui a créé une variable statique locale. Pseudocode:

voif f()
{
  static int someValue = complexFunction();
  ...
}
int complexFunction()
{
  start_thread( threadFunc() );
  wait_for_some_input_from_new_thread();
  return input_from_new_thread;
}
void threadFunc()
{
  static SomeClass s();
  ...
}

La seule solution était de désactiver cette fonctionnalité de gcc. Si vous avez besoin que votre code soit portable, ce que nous avons fait, vous ne pouvez pas de toute façon dépendre d'une fonctionnalité ajoutée dans une version gcc spécifique pour la sécurité des threads. Soi-disant C++ 0x ajoute des statiques locales thread-safe, jusque-là, c'est une magie non standard qui rend votre code non portable, donc je le déconseille. Si vous décidez de l'utiliser, je vous suggère de valider que votre version de gcc n'utilise pas un seul mutex global à cet effet en écrivant un exemple d'application. (La difficulté de la sécurité des threads est évidente du fait que même gcc ne peut pas faire les choses correctement)

17
shojtsy

Ce n'est pas vraiment répondre à vos questions tout de suite ( Charles l'a déjà fait ), mais je pense qu'il est temps de poster un lien vers cet article à nouveau. Il éclaire l'initialisation des globaux et doit être lu et compris par tous ceux qui tentent d'utiliser les variables static dans un environnement multi-thread.

6
sbi

Je pense que la phrase clé est

... thread-safe initialisation de la statique locale.

J'ai lu cela comme signifiant que seule l'initialisation de la statique se ferait de manière thread-safe. L'utilisation générale de la statique ne serait pas thread-safe.

5
Stephen C