【问题标题】:Is using unique_lock for a task that can be acomplished by lock_guard slower?是否将 unique_lock 用于可以由 lock_guard 完成的任务较慢?
【发布时间】:2013-10-24 16:52:20
【问题描述】:

我对@9​​87654321@ 存在的原因感到困惑。是吗:

  1. unique_lock更简单的界面?
  2. unique_lock性能更好?
  3. 还有别的吗?

【问题讨论】:

    标签: c++ multithreading c++11 mutex


    【解决方案1】:

    lock_guard 可以用一个状态单元来实现:一个指针或对它已锁定的Mutex 类型的引用。

    unique_lock 必须保持该状态,并且知道当前是否已锁定,因为unique_lock 可以有一个未锁定的Mutex。这意味着它必须至少有一个 bool 的额外状态。

    lock_guard 在获取和释放Mutex 时提供了一个 开销的 RAII 锁定/解锁包装器。基本上,lock_guard 意味着避免使用 RAII 处理 Mutex 上的锁的理由为零。

    unique_lock 只能达到零开销,前提是编译器可以确信您仅以可以使用 lock_guard 的方式使用它(即,构造它,然后销毁它,而不是摆弄它)。

    除了这些效率参数之外,看到lock_guard 的程序员知道它会持续到作用域结束,而无需检查作用域中的代码。看到unique_lock 的程序员必须检查变量的所有使用以了解是否是这种情况。

    但以上只是一半的原因。

    另一半是因为 C++11 的大部分线程库是基于 boost 库的,它已经实现了一个大部分独立于平台的线程库。 Boost 同时具有lock_guardunique_lock,其语义与C++11 版本几乎相同。

    所以当boost线程库被标准化时,无论是在哪里都被带入了,并且没有人消除它们。

    【讨论】:

      【解决方案2】:

      您几乎在这里回答了自己的问题 - 1) 和 2) 都是很好的理由。 std::lock_guard 是一个简单的作用域锁定对象。互斥体获取超时等特性增加了互斥体原语的复杂性,增加了执行操作所需的时间和互斥体争用的可能性。那么为什么要为不需要的东西买单呢?

      带有或不带有超时的“try_locking”是否是好的设计是另一个问题;比如线程取消,一个 C++11 没有实现的破碎设计。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-10-07
        • 1970-01-01
        • 2013-12-29
        • 1970-01-01
        • 1970-01-01
        • 2011-09-21
        相关资源
        最近更新 更多