2013-03-02 20 views
36

Ho intenzione di utilizzare boost::mutex da boost/thread/mutex.hpp. Ci sono diversi modi per bloccare/sbloccare mutex: con scoped_lock, unique_lock, lock_guard, le funzioni membro di mutex ::lock() e ::unlock() e funzioni non membro lock() e unlock().boost scoped_lock vs plain lock/unlock

Ho notato che lo boost::scoped_mutex è uno dei modi più comuni di utilizzo del mutex. Perché è preferibile alle funzioni membro ::lock() e ::unlock()?

In particolare, perché dovrei usare

{ 
    boost::scoped_lock lock(mutex) 
    // ... 
    // read/output sharing memory. 
    // ... 
} 

piuttosto che

mutex.lock() 
// ... 
// read/output sharing memory. 
// ... 
mutex.unlock() 

è scoped_lock meglio solo a causa di un certo punto di vista lo stile di codifica o è ::lock()/::unlock() non "filo abbastanza sicuro"?

risposta

62

Perché è preferibile alle funzioni membro :: lock() e :: unlock()?

Per lo stesso motivo per cui il RAII idiom è diventato popolare in generale (questa è solo una delle sue innumerevoli casi): perché si può essere sicuri che don' lasciare l'ambito corrente senza sbloccare il mutex.

avviso, che non si tratta solo di dimenticare chiamare unlock(): un'eccezione può verificarsi durante il tuo mutex è bloccato, e la chiamata a unlock() non può mai essere raggiunto, anche se non si dispone di alcun return dichiarazione tra il chiama allo lock() e chiama allo unlock().

m.lock() // m is a mutex 
// ... 
foo(); // If this throws, your mutex won't get unlocked 
// ... 
m.unlock() 

In questo caso, il distruttore del vostro scoped_lock guardia saranno invocati durante la pila svolgimento, assicurandosi che il mutex associato sempre viene rilasciato.

{ 
    boost::scoped_lock lock(m); // m is a mutex 
    // ... 
    foo(); // If this throws, your RAII wrapper will unlock the mutex 
    // ... 
} 

Inoltre, in molte situazioni questo migliorerà la leggibilità del codice, in quanto non sarà necessario aggiungere una chiamata a unlock() prima di ogni return dichiarazione.

+0

grazie per la chiara spiegazione. – Max

+0

@Max: sono contento che l'abbia aiutato –

2

è possibile utilizzare

std::lock_guard<std::mutex> lock(mutex);

se non si vuole usare la biblioteca di spinta.

Problemi correlati