boost :: unique_lock vs boost :: lock_guard

我不太了解这两个锁类之间的区别。 在boost文档中,据说, boost::unique_lock没有自动实现locking。

这是否意味着unique_locklock_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_guardunique_lock遵循RAII模式,在最简单的用例中,锁是在施工过程中获取的,在销毁过程中自动解锁。 如果这是你的用例,那么你不需要unique_lock的额外的灵活性, lock_guard会更有效率。

两者之间的主要区别是unique_lock实例不需要始终拥有它所关联的互斥量,而在lock_guard它拥有互斥量。 这意味着unique_lock将需要一个额外的标志指示它是否拥有锁和另一个额外的方法'owns_lock()'来检查。 知道这一点,我们可以解释所有额外的好处,这标志带来额外的数据设置和检查的开销

  1. 在施工过程中不需要锁,在施工过程中可以通过std::defer_lock标记,以便在施工过程中保持互斥锁。
  2. 我们可以在函数结束之前解锁它,不必等待析构函数释放它,这可以很方便。
  3. 你可以从一个函数传递锁的所有权,它是可移动的 ,不可复制的
  4. 它可以与条件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_lockboost::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也可以用于需要强调唯一锁和共享锁之间的区别。