2014-04-08 22 views
5

Le seguenti operazioni sono senza blocco per std::unique_ptr e/o std::shared_ptr?I puntatori intelligenti C++ sono bloccati?

  1. Dereferencing, cioè read(*myPtr) o myPtr->getSomething()
  2. Rimozione di riferimento, ossia con std::move(myUniquePtr) o quando un std::shared_ptr passa nell'ambito.

Nel mio caso, non accedo contemporaneamente a questi puntatori da più thread. Sono solo curioso di poterli usare esclusivamente su un thread lock-free ad alta priorità. Gli oggetti gestiti dai puntatori sono stati allocati dal thread principale prima dei callback con priorità alta e non verranno deallocati fino alla cessazione delle callback.

Grazie!

+0

uso questi http://en.cppreference.com/w/cpp/memory/shared_ptr/atomic –

+0

Si noti che 'move' e andare fuori scooe sono molto ** ** diverso. 'move' * mai * cambia il conteggio dei riferimenti. – Yakk

+0

@bryanchen quelli sono per più thread una variabile, che non è ciò che l'OP sta parlando di methinks. – Yakk

risposta

2

Tutto ciò che la norma dice è che per shared_ptr<> (20.7.2.2/4 "modello Classe shared_ptr"):

Variazioni use_count() non riflettono modifiche che possono introdurre gare di dati

Non dice che quelle modifiche in use_count() devono essere bloccate. Lo standard consente di utilizzare un mutex per impedire la corsa dei dati.

unique_ptr<> non ha alcuna promessa di impedire le corse di dati (non è destinato ad essere thread-safe per conto proprio).

+0

In pratica, tuttavia ... l'unico con qualsiasi motivo per bloccare è "uscire dall'ambito". – Yakk

+0

Quindi 'unique_ptr' non è garantito per essere bloccato? – mxdubois

+1

@mxdubois: Non penso ci sia alcun motivo per l'implementazione di 'unique_ptr' per introdurre un blocco per il dereferenziamento, ma non sono sicuro che lo standard lo proibisca. Allo stesso modo per l'operazione di spostamento. –

4

Con un'implementazione ragionevole, si può assumere:

std :: unique_ptr:

  • Tutte le operazioni su uno std :: unique_ptr sono così come le corrispondenti operazioni su un grezzo senza blocchi puntatore, perché non c'è nulla di speciale riguardo alla concorrenza.

std :: shared_ptr:

  • Tutte le operazioni, che non cambiano il conteggio di riferimento, sono come le corrispondenti operazioni su un puntatore greggio libera blocco. Ciò include le operazioni dereferencing e spostamento costruzione.
  • std :: move è lock-free, perché è solo un cast per un riferimento di rvalue.
  • Il distruttore di uno std :: shared_ptr è almeno privo di blocco come std::atomic<std::size_t> (può essere controllato con la funzione membro is_lock_free).
  • L'assegnazione di spostamento dipende dal fatto che std :: shared_ptr sul lato sinistro abbia o meno un oggetto gestito associato. Se esiste un oggetto gestito associato, è privo di blocco come il distruttore . In caso contrario, è privo di blocco come costruttore di spostamento , poiché il conteggio dei riferimenti non viene modificato.
+0

Accetterò la risposta di Burr perché cercavo principalmente ciò che era garantito, ma grazie per le informazioni extra! – mxdubois

Problemi correlati