我得到如下代码:
std::mutex mutex;
std::condition_variable condition_variable;
bool finish = false;
void test() {
while (true) {
std::unique_lock<std::mutex> lock(mutex);
condition_variable.wait(lock);
if (finish){
std::cout << "finish detected" << std::endl;
return;
}
}
}
int main() {
std::thread t(test);
std::unique_lock<std::mutex> lock(mutex);
finish = true;
lock.unlock();
//sleep(1);
condition_variable.notify_all();
std::cout << "notify_all" << std::endl;
t.join();
}
并且代码在运行时不会终止,将打印 notify_all
日志,但不会打印 finish detector
日志。如果我使用 Debug模式,代码将成功终止,因此我无法提供有关正在运行的代码的状态的明确线索,但如果我释放 sleep(1)
,代码将正常工作。
那么有人可以帮助我的代码出了什么问题吗?
最佳答案
条件变量没有状态,因此当你向它发出信号并且没有服务员时,信号就会丢失。当 condition_variable.notify_all()
在 condition_variable.wait(lock);
之前执行时,会在代码中发生这种情况。
代码未使用正确的方法来等待条件变量。正确的方法是:
- 锁定互斥锁。
- 检查状况(在此处
完成
)。 - 如果条件不满足,则等待条件变量。 The condition variable can be woken up spuriously 。转到2。
修复:
void test() {
std::unique_lock<std::mutex> lock(mutex);
while(!finish)
condition_variable.wait(lock);
std::cout << "finish detected" << std::endl;
}
还有另一个重载 condition_variable::wait
它为您执行 while
循环:
void test() {
std::unique_lock<std::mutex> lock(mutex);
condition_variable.wait(lock, [&finish]{ return finish; });
std::cout << "finish detected" << std::endl;
}
关于c++ - 即使调用了notify_all,工作线程也会在condition_variable处保持等待,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59267230/