【问题标题】:boost::unique_lock vs boost::lock_guardboost::unique_lock 与 boost::lock_guard
【发布时间】:2011-10-07 13:04:06
【问题描述】:

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

这是否意味着unique_locklock_guard 之间的主要区别在于unique_lock 我们必须显式调用lock() 函数?

【问题讨论】:

    标签: c++ boost locking


    【解决方案1】:

    首先回答您的问题。不,您不需要在 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);
    

    第一个可用于同步访问数据,但如果要使用条件变量,则需要使用第二个。

    【讨论】:

    • boost::condition 不能与 lock_guard 一起使用?
    • AFAIK condition_variable 只接受 unique_lock。它不是模板化的。如果您想要更通用的方法,可以使用condition_variable_any。但我仍然认为 any 也不适用于lock_guard。但我不确定。
    • @Guillaume07: boost::condition 一段时间以来一直是 boost::condition_variable_any 的 typedef,它支持除 unique_lock 之外的锁类型。
    【解决方案2】:

    目前投票得最多的答案很好,但直到我深入挖掘后才澄清我的疑问,因此决定与可能在同一条船上的人分享。

    首先lock_guardunique_lock 都遵循 RAII 模式,在最简单的用例中,锁在构造过程中获取,在销毁过程中自动解锁。如果这是您的用例,那么您不需要unique_lock 的额外灵活性,lock_guard 会更有效。

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

    1. 锁不必在构造时直接使用,您可以在构造期间传递标志std::defer_lock 以保持互斥体在构造期间解锁。
    2. 我们可以在函数结束前解锁它,而不必等待析构函数释放它,这很方便。
    3. 您可以通过函数传递锁的所有权,它是可移动的而不是可复制的
    4. 它可以与条件变量一起使用,因为这需要在等待条件时锁定互斥锁、条件检查和解锁。

    【讨论】:

    【解决方案3】:

    它们的实现可以在路径 .../boost/thread/locks.hpp 下找到 - 它们只是一个挨着一个:) 总而言之:

    lock_guard 是一个简短的实用程序类,它在构造函数中锁定互斥体并在析构函数中解锁,而不关心细节。

    unique_lock 有点复杂,添加了很多功能 - 但它仍然在构造函数中自动锁定。之所以称为 unique_lock,是因为它引入了“锁所有权”概念(参见 owns_lock() 方法)。

    【讨论】:

      【解决方案4】:

      如果你习惯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

      如果我/有人可以对不同 pthread_* 原语的相对成本进行基准测试,那就太好了,但最后我看了一下,pthread_mutex_* 约为 25us,而 pthread_rwlock_* 约为 20-100us,具体取决于是否已获得读锁(~10us)或未获得(~20us)或写入器(~100us)。您必须进行基准测试以确认当前数字,而且我确信它是特定于操作系统的。

      【讨论】:

      • 这并不能真正解释为什么 lock_guard 需要在那里,实际上它不需要,如果你愿意,你可以只用 unique_lock 。 lock_guard 对于有限范围的锁定来说已经足够好了,并且是为此提供的。
      【解决方案5】:

      当你需要强调唯一锁和共享锁的区别时,我认为也可以使用 unique_lock。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-01-17
        • 1970-01-01
        • 1970-01-01
        • 2012-03-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多