【发布时间】:2018-02-15 17:17:39
【问题描述】:
TL;DR
为什么std::condition_variable::wait 需要一个互斥锁作为其变量之一?
回答 1
您可以查看文档并引用:
wait... Atomically releases lock
但这不是真正的原因。这进一步验证了我的问题:为什么它首先需要它?
回答 2
谓词最有可能查询共享资源的状态,它必须被锁保护。
好的。公平的。 这里有两个问题
- 谓词查询共享资源的状态是否总是正确的?我认为是的。否则我没有意义去实现它
- 如果我不传递任何谓词(它是可选的)怎么办?
使用谓词 - 锁定有意义
int i = 0;
void waits()
{
std::unique_lock<std::mutex> lk(cv_m);
cv.wait(lk, []{return i == 1;});
std::cout << i;
}
不使用谓词 - 为什么我们不能在等待后锁定?
int i = 0;
void waits()
{
cv.wait(lk);
std::unique_lock<std::mutex> lk(cv_m);
std::cout << i;
}
注意事项
我知道这种做法没有有害影响。我只是不知道如何向自己解释为什么会这样设计?
问题
如果谓词是可选的并且没有传递给wait,为什么我们需要锁?
【问题讨论】:
-
如果您不将谓词传递给
wait,则必须在对wait的调用返回后自己检查谓词。你总是需要一些谓词,没有例外。唤醒本身是没有意义的(查找“虚假唤醒”)。 -
另见 this(描述 POSIX condvars,但 C++ 仿照 POSIX)。
-
是的。我必须自己检查谓词但是我可以自己锁定互斥锁 在
wait -
您总是需要在等待后立即锁定互斥锁。目前尚不清楚您为什么要将这些操作分开。
-
I just don't know how to explain to my self why it was design this way?选择您自己的设计,然后尝试使用它。例如,尝试实现 FIFO 队列,pop()操作等待空队列。很可能,您将无法使用您的设计中的wait来实现这一点。但是: 1. C++11 的等待方法并不是唯一可能的方法。一些库提供了另一种方法。 2.您在“不使用谓词”下的示例实际上不需要锁定互斥锁。但是这个例子本身并不是很有用。
标签: multithreading c++11 mutex wait condition-variable