我有两个用例。
答:我想同步访问两个线程的队列。
B.我希望同步两个线程对队列的访问,并使用条件变量,因为其中一个线程将等待由另一个线程存储到队列中的内容。
对于用例A,我看到使用std::lock_guard<>
的代码示例。对于用例B,我看到使用std::unique_lock<>
的代码示例。
两者之间有什么区别,我应该在哪种用例中使用哪一种?
发布于 2013-12-11 10:39:37
不同的是,您可以锁定和解锁一个std::unique_lock
。std::lock_guard
只在建筑上锁定一次,在破坏时解锁一次。
因此,对于用例B,条件变量肯定需要一个std::unique_lock
。在A种情况下,这取决于你是否需要重新锁定警卫。
std::unique_lock
还有其他允许它的特性,例如:在不立即锁定互斥锁的情况下构建它,但是可以构建RAII包装器(参见here)。
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
。
发布于 2013-12-11 10:41:08
lock_guard
和unique_lock
几乎是一回事;lock_guard
是一个受限版本,界面有限。
一个lock_guard
总是持有一个锁从它的建设到它的破坏。可以在不立即锁定的情况下创建unique_lock
,可以在其存在的任何点上解锁,并且可以将锁的所有权从一个实例转移到另一个实例。
因此,您总是使用lock_guard
,除非您需要unique_lock
的功能。condition_variable
需要一个unique_lock
。
发布于 2013-12-11 10:39:03
使用lock_guard
,除非您需要在不破坏lock
的情况下手动地在互斥之间使用unlock
。
特别是,condition_variable
在调用wait
时打开它的互斥锁。这就是为什么lock_guard
在这里是不够的。
如果您已经在使用C++17或更高版本,请考虑使用scoped_lock
作为lock_guard
的一个稍微改进的版本,具有相同的基本功能。
https://stackoverflow.com/questions/20516773
复制相似问题