condition_variable::wait_for为何会返回 std::cv_status::no_timeout

kingyo 2019-12-15 10:45:06


我有一个程序,希望在后台定时做一些事情,我就写了一个线程,每隔一段时间做一些工作。

工作线程的定时工作,是用等待一个条件变量,让他超时来实现的:
auto r = cvTimer.wait_for(lk, chrono::milliseconds(500));
这样,每隔500ms就会超时一次,于是我就可以做事情了。

如果我想停止后台定时做事情,我只要给cvTimer一个信号,那么后台线程就能得到通知,并退出

后台线程可以对auto r = cvTimer.wait_for的返回值进行检查,
如果是cv_status::timeout,表示正常工作时间到,
如果返回不是cv_status::timeout,那么应该就是想要停止工作线程。

可是很奇怪,cvTimer.wait_for会随机返回cv_status::no_timeout,导致后台线程退出(虽然不是我让他停止的)
请问大家,这是怎么回事?在我没有通知的情况下,wait_for怎么就返回了?

ubuntu下测试没有问题(g++7.4),windows下有此问题(vs2019)


#include <iostream>
#include <chrono>
#include <condition_variable>
#include <mutex>
#include <future>

using namespace std;

condition_variable cvTimer;
mutex cvMutex;
future<void> ftReturn;

void WorkThread()
{
unique_lock<mutex> lk(cvMutex);
while (true)
{
auto r = cvTimer.wait_for(lk, chrono::milliseconds(500));
if (cv_status::timeout == r)
{
//这是正常的时间到了,做一些必要的事情
cout << "Do Work" << endl;
}
else
{
//这是退出了,
//但是在我还没有调用StopWork就很有可能会进到这里来
//看文档好像有虚假唤醒这么一说,
//但是唤醒的代码只有一处,而且还未调用,怎么就唤醒了?
cout << "Stop Work" << endl;
return;
}
}
}

void StartWork()
{
ftReturn = async(launch::async, &WorkThread);
}

void StopWork()
{
unique_lock<mutex> lk(cvMutex);
cvTimer.notify_one();
lk.unlock();
ftReturn.wait();
}

int main()
{
StartWork();
this_thread::sleep_for(chrono::seconds(60));
StopWork();
}

...全文
1917 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
weixin_39800113 2022-02-16
  • 打赏
  • 举报
回复

条件变量,都是要带flag用while来判断flag的,避免虚假退出。

林荫大道中 2020-09-09
  • 打赏
  • 举报
回复
虚假退出哦!
qybao 2020-09-09
  • 打赏
  • 举报
回复
假唤醒是多线程常见的一种现象(通常的假唤醒是指多个线程同时被唤醒,但是抢到锁的只能有一个线程,所以其他没抢到锁的都属于假唤醒),这里可能是condition_variable本身实现的问题,一般建议不直接这么使用wait_for,要么用wait_for的另一个版本(带Period参数的版本,通过返回的Period判断是否是假醒),要么改成wait_until 可以参考以下 https://www.bookstack.cn/read/Cpp_Concurrency_In_Action/content-appendix_D-D.2-chinese.md
kingyo 2019-12-16
  • 打赏
  • 举报
回复
这是windows实现的bug?

64,637

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧