boost :: shared_ptr è sicuro usarlo in più thread?

Stavo cercando di trovare la risposta per qualche tempo, ma ho fallito.

Supponiamo che abbiamo un shared_ptr creato da un thread. Quindi passiamo questo shared_ptr ad altri 2 thread (usando qualche coda per esempio). Quindi da questo momento ci sono 2 copie del file shared_ptr originale, che punta allo stesso puntatore raw. Entrambi i thread del proprietario prenderanno le loro copie di questo shared_ptr dalla coda. Quindi lo passeranno a un altro thread o lo distruggeranno.

La domanda è – è sicuro? Il puntatore non elaborato verrà distrutto correttamente (non vi sarà alcuna gara per fare riferimento al contatore?) inserisci la descrizione dell'immagine qui

Lo stato dei documenti di potenziamento :

Diverse istanze di shared_ptr possono essere “scritte su” (accessibili tramite operazioni mutabili come operator = o reset) contemporaneamente da più thread ( anche quando queste istanze sono copie e condividono lo stesso conteggio di riferimento al di sotto ) .

(sottolineatura mia)

Quindi il punto cruciale qui è se copiate boost::shared_ptr s tra i thread o meno. Se crei delle copie (il modo “sicuro” di usare shared_ptr s) non hai preoccupazioni per la sicurezza dei thread. Se tuttavia si shared_ptr il shared_ptr per riferimento o puntatore e quindi si utilizza lo stesso shared_ptr in thread diversi, è necessario preoccuparsi della sicurezza del thread, come descritto nei documenti.

Lo standard C ++ non ha quasi nessuna garanzia per quanto riguarda la sicurezza del filo. Il numero di riferimento di std::shared_ptr è l’unica eccezione: è garantito il comportamento come variabile a cui si accede in modo atomico. Credo che questo sia codificato in questa frase in §20.7.2.2 / 4:

Le modifiche in use_count() non riflettono le modifiche che possono introdurre le corse di dati.

boost::shared_ptr offre le stesse garanzie :

Gli oggetti shared_ptr offrono lo stesso livello di sicurezza dei thread dei tipi built-in. Un’istanza shared_ptr può essere “letta” … simultaneamente da più thread. Diverse istanze di shared_ptr possono essere “scritte su” … contemporaneamente da più thread (anche quando queste istanze sono copie e condividono lo stesso conteggio di riferimento al di sotto).

Vorrei pubblicare il mio commento per il conteggio dei riferimenti nel puntatore condiviso di boost nei casi di utilizzo di più thread. Il commento è di rispondere alla domanda “c’è qualche condizione di competizione nel conteggio dei riferimenti del puntatore boost condiviso?”

La mia risposta semplice è “No” almeno dopo l’enfasi 1.35 per il compilatore più mainstream. L’implementazione boost chiamata “add_ref_copy” definita in boost / detail / shared_count.hpp. Questa funzione invocherà la corrispondente funzione atomica definita per il singolo compilatore. Ad esempio, la versione di Windows chiamerà “BOOST_INTERLOCKED_INCREMENT” per incrementare il conteggio in modo atomico (vedi dettagli in dettaglio \ sp_counted_base_w32.hpp). E il Linux gcc per X86 chiamerà atomic_increment (…) (vedi i dettagli in dettaglio \ sp_counted_base_gcc_x86.hpp). Ogni singolo compilatore implementava il meccanismo thread-safe per assicurarsi che l’aggiornamento del conteggio dei riferimenti fosse efficiente. Alcuni pezzi di codice sono anche scritti in assembly.

Ora c’è un avvertimento nella mia semplice risposta. Devi davvero assicurarti che il tuo compilatore sia incluso nell’elenco benedetto di boost per il conteggio dei riferimenti sicuro per più thread. Se non sei sicuro di poter definire “BOOST_SP_USE_PTHREADS” che spinge a utilizzare la libreria pthread per aggiornare atomicamente il conteggio dei riferimenti (includendo boost / detail / sp_counted_base_pt.hpp per la soluzione pthread).