boost :: unique_lock vs boost :: lock_guard
我不太了解这两个锁类之间的区别。 在boost文档中,据说, boost::unique_lock
没有自动实现locking。
这是否意味着unique_lock
和lock_guard
之间的主要区别是unique_lock
必须显式调用lock()
函数?
首先回答你的问题。 不,你不需要在unique_lock上调用锁。 见下文:
unique_lock只是一个具有更多function的锁类。 在大多数情况下,lock_guard会做你想做的事情,而且是足够的。
unique_lock有更多的function提供给你。 例如,如果您需要超时,或者如果您想将locking推迟到比构造对象更晚的时间,则需要定时等待。 所以它高度取决于你想要做什么。 顺便说一句:下面的代码片段做同样的事情。
boost::mutex mutex; boost::lock_guard<boost::mutex> lock(mutex);
boost::mutex mutex; boost::unique_lock<boost::mutex> lock(mutex);
第一个可以用来同步对数据的访问,但是如果你想使用条件variables,你需要去第二个。
目前最好的投票答案是好的,但是直到我挖得更深一点,才明白我的怀疑,所以决定与可能在同一条船上的人分享。
首先lock_guard
和unique_lock
遵循RAII模式,在最简单的用例中,锁是在施工过程中获取的,在销毁过程中自动解锁。 如果这是你的用例,那么你不需要unique_lock
的额外的灵活性, lock_guard
会更有效率。
两者之间的主要区别是unique_lock
实例不需要始终拥有它所关联的互斥量,而在lock_guard
它拥有互斥量。 这意味着unique_lock
将需要一个额外的标志指示它是否拥有锁和另一个额外的方法'owns_lock()'来检查。 知道这一点,我们可以解释所有额外的好处,这标志带来额外的数据设置和检查的开销
- 在施工过程中不需要锁,在施工过程中可以通过
std::defer_lock
标记,以便在施工过程中保持互斥锁。 - 我们可以在函数结束之前解锁它,不必等待析构函数释放它,这可以很方便。
- 你可以从一个函数传递锁的所有权,它是可移动的 ,不可复制的 。
- 它可以与条件variables一起使用,因为这要求在等待条件时互斥体被locking,条件检查和解锁。
他们的实现可以在path下find… / boost / thread / locks.hpp – 他们坐在一个旁边其他:)总结一下:
lock_guard是一个简短的实用程序类,它在构造函数中locking互斥锁,并在析构函数中解锁,而不关心细节。
unique_lock稍微复杂一点,增加了很多function – 但它仍然在构造函数中自动locking。 它被称为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
如果我/某人可以基准testing不同pthread_ *原语的相对成本,那将是非常好的,但是最后我看了, pthread_mutex_*
是〜25us,而pthread_rwlock_*
是〜20-100us,取决于读锁是否已经(〜10us)或不是(〜20us)或作家(〜100us)。 你将不得不基准确认当前的数字,我相信这是非常特定的操作系统。
我认为unique_lock也可以用于需要强调唯一锁和共享锁之间的区别。