为啥 std::condition_variable 采用 unique_lock 而不是 lock_guard? [复制]

Posted

技术标签:

【中文标题】为啥 std::condition_variable 采用 unique_lock 而不是 lock_guard? [复制]【英文标题】:Why does std::condition_variable take a unique_lock instead of a lock_guard? [duplicate]为什么 std::condition_variable 采用 unique_lock 而不是 lock_guard? [复制] 【发布时间】:2018-08-10 07:06:46 【问题描述】:

std::condition_variable 使用如下:

std::condition_variable cv;
...
std::unique_lock<std::mutex> lk(m);
cv.wait(lk, []return processed;);

在我看来有一个有趣的问题。 unique_lock 可以推迟,它可以被交换掉。通过代码设计,它可能有许多其他原因,不一定是它实际上没有被锁定的严重错误。例如。

std::unique_lock<std::mutex> lk(m, std::try_to_lock_t); // or  std::defer_lock_t
// Try to lock fails.
cv.wait(lk, []return processed;);

为什么不通过使std::conditional_variablelock_guard 一起工作来强制锁定情况呢?那么你将很难进入这种情况。事实上,唯一的方法就是这样做:

// m is not already locked
std::lock_gaurd<std::mutex> lk(m, std::adopt_lock);
cv.wait(lk, []return processed;);

而不是unique_lock 提供的多种方式。 condition_variable 上使用unique_lock 而不是lock_guard 是否有技术原因

【问题讨论】:

问题标题正是这里提出的问题。接受的答案涵盖了所有基础(甚至比这里的当前答案还要多)。 OP 确实做到了 mutexunique_lock,但投票率最高的答案涵盖了更多内容,包括关于为什么不 lock_guard 的专门段落。 @rubenvb 你是绝对正确的。当我阅读答案时,我一定错过了那段。感谢您的帮助。 没问题。重复项主要用于引导用户和访问者获得良好的综合答案。这不是手腕上的一记耳光或任何东西。只是一个303 See other。 【参考方案1】:

条件变量需要能够锁定和解锁互斥体,lock_guard 不允许这样做。 lock_guard 也不允许访问大多数条件变量实现可能需要的互斥锁本身。

【讨论】:

【参考方案2】:

lock_guardunique_lock 非常相似。然而,lock_guard 锁定构造并解锁破坏。使用condition_variable,互斥锁需要可以多次锁定和解锁。

您基本上可以在任何地方使用unique_locks,但它们比简单的lock_guard 产生更多开销。

std::condition_variable 仅适用于 std::unique_lock; 此限制允许在某些平台上实现最大效率。 std::condition_variable_any 提供了一个有效的条件变量 与任何 BasicLockable 对象,例如 std::shared_lock。

取自cppreference

【讨论】:

以上是关于为啥 std::condition_variable 采用 unique_lock 而不是 lock_guard? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

为啥 DataGridView 上的 DoubleBuffered 属性默认为 false,为啥它受到保护?

为啥需要softmax函数?为啥不简单归一化?

为啥 g++ 需要 libstdc++.a?为啥不是默认值?

为啥或为啥不在 C++ 中使用 memset? [关闭]

为啥临时变量需要更改数组元素以及为啥需要在最后取消设置?

为啥 CAP 定理中的 RDBMS 分区不能容忍,为啥它可用?