2009-08-13 15 views
56

Nel codice esempioLe variabili statiche della funzione sono thread-safe in GCC?

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

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

Nella pagina man di gcc, trovato il -fno-threadsafe-statica opzione della riga di comando:

Non emettere il codice aggiuntivo per utilizzare le routine specificate nella ++ ABI C per threadsafe inizializzazione della statica locale . È possibile utilizzare questa opzione per ridurre leggermente la dimensione del codice nel codice che non deve essere thread-safe.

  1. significa, che statica locali sono thread-safe di default con GCC? Quindi nessuna ragione per porre protezioni esplicite per es. con pthread_mutex_lock/unlock?

  2. Come scrivere codice portatile: come verificare se il compilatore aggiungerà le proprie protezioni? O è meglio disattivare questa funzionalità di GCC?

risposta

41
  1. No, significa che l'inizializzazione di locali static s è thread-safe.

  2. Sicuramente si vuole lasciare questa funzione abilitata. L'inizializzazione sicura dei thread di locali static s è molto importante. Se hai bisogno di accedere in genere ai thread locali da static s, dovrai aggiungere tu stesso le protezioni appropriate.

+1

quale utilizzo è inizializzato con thread-safe se non si dispone dell'accesso thread-safe (funzione locale)? – xtofl

+10

Per inizializzare il mutex che userai per controllare l'accesso ad altre variabili. – AProgrammer

+6

Se è necessario scrivere codice portatile, non è possibile fare affidamento sull'inizializzazione thread-safe delle statistiche delle funzioni. Ad esempio MS C++ non lo fa. Quindi non sono d'accordo sul punto 2 - puoi tranquillamente disabilitarlo, se vuoi scrivere codice portatile, ma non devi usare la funzione statica dove la sicurezza del thread è importante ;-) – hirschhornsalz

5

Penso che la frase chiave è

... thread-safe inizializzazione di statica locali.

Ho letto questo nel senso che è solo l'inizializzazione della statica che verrebbe eseguita in modalità thread-safe. L'uso generale della statica non sarebbe sicuro per i thread.

6

Questo non risponde alle tue domande immediatamente (Charles already did that), ma penso che sia ora di pubblicare nuovamente un collegamento a this article. Getta luce sull'inizializzazione dei globals e dovrebbe essere letto e compreso da chiunque tenti di utilizzare le variabili static in un ambiente multi-thread.

17

Abbiamo riscontrato seri problemi con il codice di blocco generato da GCC 3.4 per proteggere l'inizializzazione statica locale. Quella versione utilizzava 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.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(); 
    ... 
} 

L'unica soluzione era disabilitare questa funzionalità 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 anche gcc non riesce a farlo bene)

+1

Ho affrontato una situazione molto simile e mi ha fatto porre questa domanda qui su SO – CsTamas

+1

'static SomeClass s();' è una dichiarazione di funzione –

Problemi correlati