2013-06-14 23 views
37

Nota: questa domanda riguarda C++ 11. La risposta alla stessa domanda in C++ 17 (o versioni successive) potrebbe essere cambiata. Per ulteriori informazioni:Qual è il modo migliore per bloccare più std :: mutex?


Quando vogliamo bloccare più std::mutex 'Es, usiamo std::lock(). Ma std::lock() non fornisce funzionalità RAII.

Quando si desidera bloccare un std::mutex in modo RAII, viene utilizzato std::lock_guard. Ma std::lock_guard non può bloccare più std::mutex in modo sicuro.

Esiste un modo per sfruttare i vantaggi di entrambi i metodi per bloccare più std::mutex in modo RAII?

risposta

61

Sì, è possibile utilizzare uno std::unique_lock con std::defer_lock. Dice a unique_lock di non bloccare immediatamente il mutex, ma di costruire il wrapper RAII.

std::unique_lock<std::mutex> lk1(mutex1, std::defer_lock); 
std::unique_lock<std::mutex> lk2(mutex2, std::defer_lock); 
std::lock(lk1, lk2); 

Grazie alla sua natura variadic std::lock non è vincolato a due soli argomenti, ma può essere utilizzato con il maggior numero di argomenti come il compilatore ha il supporto per.

Howard Hinnant ha anche sottolineato un aspetto interessante delle prestazioni, è possibile controllare il collegamento this se si è interessati. Affronta problemi di prestazioni e mostra che std::lock può essere implementato in modo efficiente, posso anche raccomandare di leggere tutti i commenti in quel post.

+12

+1 E 'std :: lock' non è limitato a solo due blocchi. Può gestire qualsiasi numero (fino ai limiti del compilatore su modelli variadici). –

+2

Ci sono stati dubbi sull'efficienza di 'std :: lock'. Vedi questa risposta: http://stackoverflow.com/a/14525010/576911 per rispondere a queste preoccupazioni. –

Problemi correlati