2009-12-26 13 views
21

Selon les ressources suivantes, en C++ (Specially Visual C++) l'initialisation de variable statique portée n'est pas thread-safe. Mais, les variables statiques globales sont sûres.Est-ce que l'initialisation de la variable de membre statique C++ est sûre pour les threads?

Thread-safe static variables without mutexing?

http://blogs.msdn.com/oldnewthing/archive/2004/03/08/85901.aspx

Donc, suit avec le code thread-safe variable de membre statique?

class TestClass 
{ 
public: 
    static MyClass m_instance; 
} 

Myclass TestClass::m_instance; 

Merci d'avance!

+1

Cela semble vrai même 5 ans après: http://blogs.msdn.com/b/vcblog/archive/2013/12/02/c-11-14-core-language-features-in-vs-2013- et-le-nov-2013-ctp.aspx (voir "statique de la magie") :) – mlvljr

+0

Apparemment, [VS 2015 corrige finalement ceci] (http://stackoverflow.com/a/28098631/1505939) –

Répondre

32

Il s'agit plus de variables statiques à portée de fonction que de toutes les autres variables statiques, plutôt que de variables globales.

Toutes les variables statiques hors fonction sont construites avant main(), alors qu'il n'y a qu'un seul thread actif. Les variables statiques de la portée de la fonction sont construites la première fois que leur fonction conteneur est appelée. La norme est muette sur la question de savoir comment les statiques de niveau fonction sont construites lorsque la fonction est appelée sur plusieurs threads. Cependant, chaque implémentation avec laquelle j'ai travaillé utilise un verrou autour du constructeur (avec un drapeau vérifié deux fois) pour garantir la sécurité des threads.

+4

La norme est également muette sur la façon dont les statistiques statiques non-fonctionnelles sont construites avec plusieurs threads. IIRC tout ce qui est garanti est que l'objet est initialisé avant que tout autre code dans l'unité de traduction soit exécuté (c'est-à-dire, le code n'est pas appelé par les initialiseurs). Si vous considérez que le code peut être dans une DLL chargée après l'exécution de main(), vous voyez que c'est le meilleur qui peut être garanti. C'est la spécification de threading particulière qui apporte d'autres garanties, pas la norme C++. –

+0

g ++ (comme dans GCC) garantit l'initialisation sans risque des variables statiques globales et fonctionnelles et plante le code requis pour bloquer les autres threads lors de l'initialisation. –

+7

gcc utilise des verrous pour rendre les statistiques de niveau de fonction threadsafe (peut être désactivé par un indicateur). La plupart des versions (toutes?) De Visual C++ n'ont pas de statique de niveau de fonction threadsafe. – tony

2

Oui (*). Lorsque les statistiques globales sont initialisées, il n'y a qu'un seul thread autour et tous les constructeurs sont appelés. Ce n'est pas vrai pour la statique de la fonction, cependant. (*) On peut éventuellement rendre la statique globale non thread-safe en créant des threads dans certains constructeurs et en planifiant quelques étapes d'initialisation sur ces threads. Dans ce cas, les règles de sécurité habituelles s'appliquent.

+0

Je peux créer des discussions dans les constructeurs si c'est le dernier programme que j'écris ;-) – Varuna

+1

@Varuna: parfois vous n'avez pas le choix ou vous ne savez même pas que les threads sont créés dans vos constructeurs. Cela se produit généralement lorsque des objets en cours de construction utilisent des bibliothèques tierces. – Rom