Le variabili statiche di funzione sono thread-safe in GCC?

Nel codice di esempio

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

compilato con GCC è garantito che b verrà creato e inizializzato in modo thread-safe?

Nella pagina man di gcc, trova l’opzione della riga di comando -fno-threadsafe-statics :

Non emettere il codice aggiuntivo per utilizzare le routine specificate nell’ABI C ++ per l’inizializzazione thread-safe delle statistiche locali. È ansible utilizzare questa opzione per ridurre leggermente la dimensione del codice nel codice che non deve necessariamente essere thread-safe.

  1. Significa che le statiche locali sono prive di thread per impostazione predefinita con GCC? Quindi non c’è motivo di porre protezioni esplicite ad es. Con pthread_mutex_lock/unlock ?

  2. Come scrivere codice portatile – come verificare se il compilatore aggiungerà le sue guardie? O è meglio distriggersre questa funzionalità di GCC?

  1. No, significa che l’ inizializzazione delle s static locali è thread-safe.

  2. Sicuramente vuoi lasciare questa funzione abilitata. L’inizializzazione sicura dei thread delle static locali è molto importante. Se hai bisogno di accesso generalmente al thread-safe alle static locali, allora dovrai aggiungere tu stesso le guardie appropriate.

Abbiamo avuto seri problemi con il codice di blocco generato da GCC 3.4 per proteggere l’inizializzazione statica locale. Quella versione usava un mutex condiviso globale per proteggere tutto e qualsiasi inizializzazione statica che porta a un deadlock nel nostro codice. Abbiamo avuto una variabile statica locale inizializzata da un risultato di una funzione, che ha avviato un altro thread, che ha creato una variabile statica locale. pseudocodice:

 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(); ... } 

L’unica soluzione era disabilitare questa funzione di gcc. Se hai bisogno che il tuo codice sia portatile, cosa che abbiamo fatto, non puoi comunque dipendere da una funzionalità aggiunta in una specifica versione di gcc per la sicurezza dei thread. Presumibilmente C ++ 0x aggiunge statiche locali thread-safe, fino ad allora questa è magia non standard che rende il tuo codice non portatile, quindi sto sconsiderandolo. Se decidi di usarlo, ti suggerisco di verificare che la tua versione di gcc non usi un singolo mutex globale per questo scopo scrivendo un’applicazione di esempio. (La difficoltà della sicurezza del thread è evidente dal fatto che persino gcc non riesce a farlo bene)

Questo non risponde alle tue domande ( Charles lo ha già fatto ), ma penso che sia ora di pubblicare nuovamente un link a questo articolo . Getta luce sull’inizializzazione dei globali e dovrebbe essere letto e compreso da chiunque tenti di utilizzare variabili static in un ambiente multi-thread.

Penso che la frase chiave sia

inizializzazione thread-safe di statica locale.

Ho letto questo nel senso che è solo l’inizializzazione della statica che verrebbe eseguita in modo sicuro per i thread. L’uso generale della statica non sarebbe sicuro per i thread.