You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 13:52:37