2009-12-26 12 views
21

In base alle seguenti risorse, l'inizializzazione della variabile statica con scope C++ (Specially Visual C++) non è thread-safe. Ma le variabili statiche globali sono sicure.L'inizializzazione della variabile membro C++ è protetta da thread?

Thread-safe static variables without mutexing?

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

Quindi, sta seguendo con il codice membro statico variabile thread-safe?

class TestClass 
{ 
public: 
    static MyClass m_instance; 
} 

Myclass TestClass::m_instance; 

Grazie in anticipo!

+1

Sembra vero anche 5 anni dopo: http://blogs.msdn.com/b/vcblog/archive/2013/12/02/c-11-14-core-language-features-in-vs-2013- e-the-nov-2013-ctp.aspx (vedi "Statistica magica") :) – mlvljr

+0

Apparentemente, [VS 2015 risolve definitivamente questo] (http://stackoverflow.com/a/28098631/1505939) –

risposta

32

È più una questione di variabili statiche basate su una funzione rispetto a qualsiasi altro tipo di variabile statica, piuttosto che obiettivo e globale.

Tutte le variabili statiche del campo non funzionale vengono create prima di main(), mentre esiste un solo thread attivo. Le variabili statiche di scope della funzione vengono costruite la prima volta che viene chiamata la loro funzione di contenimento. Lo standard tace sulla questione di come vengono costruite le statistiche a livello di funzione quando la funzione viene chiamata su più thread. Tuttavia, ogni implementazione con cui ho lavorato utilizza un blocco attorno al costruttore (con un flag due volte controllato) per garantire la sicurezza del thread.

+4

Lo standard non tiene conto del modo in cui le statiche con ambito non funzionale vengono costruite con più thread. IIRC tutto ciò che è garantito è che l'oggetto è inizializzato prima che venga eseguito qualsiasi altro codice nell'unità di traduzione (cioè, codice non chiamato dagli inizializzatori). Se si considera che il codice potrebbe essere in una DLL caricata dopo che main() inizia a essere eseguito, si vede che questo è il migliore che possa essere realisticamente garantito. È la specifica specifica del threading che offre ulteriori garanzie, non lo standard C++. –

+0

g ++ (come in GCC) garantisce l'inizializzazione thread-safe delle variabili statiche globali e di funzione e installa il codice richiesto per bloccare altri thread durante l'inizializzazione. –

+7

gcc utilizza i blocchi per rendere thread-safe a livello di funzione (può essere disabilitato da un flag). La maggior parte delle versioni (tutte?) Di Visual C++ NON dispongono di statistiche a livello di funzione thread-safe. – tony

2

Sì (*). Quando la statistica globale viene inizializzata, c'è solo un thread in giro e tutti i costruttori sono chiamati su di esso. Questo non è vero per la statica della funzione, però.

(*) Uno può rendere statiche globali non thread-safe creando thread in alcuni costruttori e pianificando alcune fasi di inizializzazione su questi thread. In questo caso si applicano le normali regole sulla sicurezza dei fili.

+0

Posso creare discussioni nei costruttori se è l'ultimo programma che sto scrivendo ;-) – Varuna

+1

@Varuna: a volte non hai scelta o non sai nemmeno che i thread sono stati creati nei tuoi costruttori. Questo di solito accade quando gli oggetti che vengono costruiti utilizzano librerie di terze parti. – Rom

Problemi correlati