C++ condition_variable用time_point::max()调用wait_until()不阻塞线程问题
问题分析与修复
核心问题:VS2013标准库的实现缺陷
VS2013的std::condition_variable::wait_until对std::chrono::steady_clock::time_point::max()的处理存在bug——它没有将这个值识别为“永久阻塞”,而是直接判定为超时,导致线程每次调用wait_until都会立刻返回false,进入else分支打印“Waiting...”,陷入无限循环。
代码逻辑冗余问题
你定义的全局变量dueAt完全是多余的:线程函数threadFunc每次进入循环都会把dueAt重置为max(),通知线程notifierThread修改的dueAt会被直接覆盖,而且wait_until的超时时间是调用时传入的参数,根本不会读取这个全局变量,所以这个变量对逻辑没有任何帮助,反而增加了混乱。
修复方案
方案1:改用无超时的wait(最符合你的需求)
既然你的预期是线程阻塞直到被唤醒,不需要超时逻辑,直接用condVar.wait(lock, [](){ return pred; })即可,避开VS2013的wait_untilbug。
修改后的threadFunc:
void threadFunc() { for (;;) { std::unique_lock<std::mutex> lock(mut); if (condVar.wait(lock, [](){ return pred; })) { std::cout << "Ready..." << std::endl; pred = false; } } }
方案2:如果必须使用wait_until(针对VS2013的bug适配)
将超时参数改为std::chrono::system_clock::time_point::max(),VS2013对这个值的处理是正确的,能实现永久阻塞:
void threadFunc() { for (;;) { std::unique_lock<std::mutex> lock(mut); if (condVar.wait_until(lock, std::chrono::system_clock::time_point::max(), [](){ return pred; })) { std::cout << "Ready..." << std::endl; pred = false; } else { std::cout << "Waiting..." << std::endl; } } }
同时记得移除多余的dueAt全局变量,因为它完全没用。
额外说明
VS2013是比较老旧的编译器,对C++11标准的支持存在不少缺陷,这类标准库实现的bug在后续版本(比如VS2015及以后)已经被修复。如果条件允许,建议升级编译器版本。
内容的提问来源于stack exchange,提问作者Seektech
相关产品推荐
相关产品推荐

