【发布时间】:2011-10-07 13:04:06
【问题描述】:
我不太了解这两个锁类之间的区别。
在 boost 文档中说,boost::unique_lock 不会自动实现锁定。
这是否意味着unique_lock 和lock_guard 之间的主要区别在于unique_lock 我们必须显式调用lock() 函数?
【问题讨论】:
我不太了解这两个锁类之间的区别。
在 boost 文档中说,boost::unique_lock 不会自动实现锁定。
这是否意味着unique_lock 和lock_guard 之间的主要区别在于unique_lock 我们必须显式调用lock() 函数?
【问题讨论】:
首先回答您的问题。不,您不需要在 unique_lock 上调用 lock。见下文:
unique_lock 只是一个具有更多功能的锁类。在大多数情况下,lock_guard 会做你想做的事,而且就足够了。
unique_lock 为您提供更多功能。例如,如果您需要超时,或者您想将锁定推迟到对象构造之后的某个时间点,则进行定时等待。所以这在很大程度上取决于你想做什么。
顺便说一句:下面的代码 sn-ps 做同样的事情。
boost::mutex mutex;
boost::lock_guard<boost::mutex> lock(mutex);
boost::mutex mutex;
boost::unique_lock<boost::mutex> lock(mutex);
第一个可用于同步访问数据,但如果要使用条件变量,则需要使用第二个。
【讨论】:
condition_variable 只接受 unique_lock。它不是模板化的。如果您想要更通用的方法,可以使用condition_variable_any。但我仍然认为 any 也不适用于lock_guard。但我不确定。
boost::condition 一段时间以来一直是 boost::condition_variable_any 的 typedef,它支持除 unique_lock 之外的锁类型。
目前投票得最多的答案很好,但直到我深入挖掘后才澄清我的疑问,因此决定与可能在同一条船上的人分享。
首先lock_guard 和unique_lock 都遵循 RAII 模式,在最简单的用例中,锁在构造过程中获取,在销毁过程中自动解锁。如果这是您的用例,那么您不需要unique_lock 的额外灵活性,lock_guard 会更有效。
两者之间的主要区别在于unique_lock 实例不需要始终拥有与其关联的互斥锁,而在lock_guard 中它拥有互斥锁。这意味着unique_lock 需要有一个额外的标志来指示它是否拥有锁和另一个额外的方法'owns_lock()' 来检查它。知道了这一点,我们就可以解释这个标志带来的所有额外好处,以及要设置和检查的额外数据的开销
std::defer_lock 以保持互斥体在构造期间解锁。【讨论】:
它们的实现可以在路径 .../boost/thread/locks.hpp 下找到 - 它们只是一个挨着一个:) 总而言之:
lock_guard 是一个简短的实用程序类,它在构造函数中锁定互斥体并在析构函数中解锁,而不关心细节。
unique_lock 有点复杂,添加了很多功能 - 但它仍然在构造函数中自动锁定。之所以称为 unique_lock,是因为它引入了“锁所有权”概念(参见 owns_lock() 方法)。
【讨论】:
如果你习惯pthreads(3):
boost::mutex = pthread_mutex_*
boost::unique_lock = pthread_rwlock_* 用于获取写/独占锁(即pthread_rwlock_wrlock)boost::shared_lock = pthread_rwlock_* 用于获取读/共享锁(即pthread_rwlock_rdlock)是的,boost::unique_lock 和 boost::mutex 函数的功能类似,但 boost::mutex 通常是获取和释放的更轻量级的互斥体。也就是说,已经获得锁的shared_lock 更快(并且允许并发),但获得unique_lock 的成本相对较高。
您必须深入了解实现细节,但这就是预期差异的要点。
说到性能:这里有一个比较有用的延迟比较:
http://www.eecs.berkeley.edu/%7Ercs/research/interactive_latency.html
如果我/有人可以对不同 pthread_* 原语的相对成本进行基准测试,那就太好了,但最后我看了一下,pthread_mutex_* 约为 25us,而 pthread_rwlock_* 约为 20-100us,具体取决于是否已获得读锁(~10us)或未获得(~20us)或写入器(~100us)。您必须进行基准测试以确认当前数字,而且我确信它是特定于操作系统的。
【讨论】:
当你需要强调唯一锁和共享锁的区别时,我认为也可以使用 unique_lock。
【讨论】: