2009-08-13 8 views
56

Im BeispielcodeSind statische Variablen in GCC threadsicher?

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

mit GCC zusammengestellt ist gewährleistet, dass b erstellt und in einem Thread-sichere Weise initialisiert werden?

In Manpage gcc, fanden die -fno-THREAD-Statik Befehlszeilenoption:

Sie in dem C++ ABI für THREAD nicht den zusätzlichen Code emittieren angegeben, die Routinen zu verwenden, Initialisierung der lokalen Statik. Sie können diese Option verwenden, um Code-Größe im Code leicht zu reduzieren, dass nicht Thread-sicher sein muss.

  1. Bedeutet es, dass lokale Statik mit GCC Thread-sicher ist standardmäßig? Es gibt also keinen Grund, explizit zu schützen, z.B. mit pthread_mutex_lock/unlock?

  2. Wie man tragbaren Code schreibt - wie man prüft, ob Compiler seine Wachen hinzufügt? Oder ist es besser, diese Funktion von GCC auszuschalten?

Antwort

41
  1. Nein, bedeutet dies, dass die Initialisierung der lokalen static s threadsicher ist.

  2. Sie möchten diese Funktion auf jeden Fall aktiviert lassen. Thread-safe Initialisierung von lokalen static s ist sehr wichtig. Wenn Sie generell einen thread-sicheren Zugriff auf lokale static s benötigen, müssen Sie die entsprechenden Schutzvorrichtungen selbst hinzufügen.

+1

Was ist eine Thread-sichere Initialisierung, wenn Sie keinen thread-sicheren Zugriff (lokale Funktion) haben? – xtofl

+10

Um den Mutex zu initialisieren, verwenden Sie den Zugriff auf andere Variablen. – AProgrammer

+6

Wenn Sie portablen Code schreiben müssen, können Sie sich nicht auf die Thread-sichere Initialisierung der Funktionsstatik verlassen. Zum Beispiel macht MS C++ es nicht. Also ich stimme nicht zu Punkt 2 - Sie können es sicher deaktivieren, wenn Sie tragbaren Code schreiben möchten, aber Sie müssen nicht Funktionsstatik verwenden, wo Threadsicherheit wichtig ist ;-) – hirschhornsalz

5

Ich denke, dass der Schlüsselbegriff

... thread-safe Initialisierung von lokale Statik ist.

Ich lese dies als Bedeutung, dass es nur die Initialisierung der Statik ist, die in einer thread-sicheren Weise getan werden würde. Der allgemeine Einsatz von Statik wäre nicht threadsicher.

6

Dies ist nicht wirklich beantworten Ihre Fragen sofort (Charles already did that), aber ich denke, es ist Zeit, einen Link zu this article wieder zu veröffentlichen. Es wirft ein Licht auf die Initialisierung von Globals und sollte von allen gelesen und verstanden werden, die versuchen, static Variablen in einer Multi-Thread-Umgebung zu verwenden.

17

Wir hatten schwerwiegende Probleme mit dem Sperrcode, der von GCC 3.4 generiert wurde, um die lokale statische Initialisierung zu schützen. Diese Version verwendet einen globalen geteilten Mutex zum Schutz aller statischen Initialisierung, die zu einem Deadlock in unserem Code führen. Wir hatten eine lokale statische Variable initialisiert von einem Ergebnis einer Funktion, die einen anderen Thread startete, der eine lokale statische Variable erzeugte.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(); 
    ... 
} 

Die einzige Lösung war, diese Funktion von gcc zu deaktivieren. Wenn Sie möchten, dass Ihr Code portabel ist, was wir auch getan haben, können Sie sich nicht auf eine Funktion verlassen, die in einer bestimmten GCC-Version zur Thread-Sicherheit hinzugefügt wurde. Angeblich fügt C++ 0x thread-sichere lokale Statiken hinzu, bis dahin ist das eine nicht standardisierte Magie, die Ihren Code nicht portierbar macht, deshalb rate ich dagegen. Wenn Sie sich entscheiden, es zu verwenden, empfehle ich Ihnen, zu validieren, dass Ihre gcc-Version keinen einzigen globalen Mutex für diesen Zweck verwendet, indem Sie eine Beispielanwendung schreiben. (Die Schwierigkeit der Thread-Sicherheit ergibt sich aus der Tatsache, dass selbst gcc das nicht richtig macht)

+1

Ich habe eine sehr ähnliche Situation konfrontiert, und es machte mich diese Frage hier auf SO – CsTamas

+1

'statische SomeClass s();' ist eine Funktionsdeklaration –