我有两个用例。
A. 我想同步访问两个线程的队列。
B. 我想同步两个线程对队列的访问并使用条件变量,因为其中一个线程将等待另一个线程将内容存储到队列中。
对于用例 AI,请参阅使用std::lock_guard<>. 对于用例 BI,请参阅使用std::unique_lock<>.
std::lock_guard<>
std::unique_lock<>
两者之间有什么区别,我应该在哪个用例中使用哪一个?
不同之处在于您可以锁定和解锁std::unique_lock. std::lock_guard只会在建造时锁定一次,在破坏时解锁。
std::unique_lock
std::lock_guard
因此,对于用例 B,您肯定需要一个std::unique_lock条件变量。情况 A 取决于您是否需要重新锁定防护装置。
std::unique_lock具有允许它的其他功能,例如:在不立即锁定互斥锁的情况下构建但构建 RAII 包装器
std::lock_guard还提供了一个方便的 RAII 包装器,但不能安全地锁定多个互斥锁。当您需要有限范围的包装器时,可以使用它,例如:成员函数:
class MyClass{ std::mutex my_mutex; void member_foo() { std::lock_guard<mutex_type> lock(this->my_mutex); /* block of code which needs mutual exclusion (e.g. open the same file in multiple threads). */ //mutex is automatically released when lock goes out of scope } };
通过 chmike 澄清一个问题,默认情况下std::lock_guard和std::unique_lock是相同的。因此,在上述情况下,您可以替换std::lock_guard为std::unique_lock. 但是,std::unique_lock可能会有更多的开销。
请注意,这些天(自 C++17 起)应该使用std::scoped_lock而不是std::lock_guard.
std::scoped_lock