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

为何std::condition_variable在std::this_thread::sleep_for置于unique_lock域内时失效?

线程同步问题解析:锁作用域内Sleep导致的无输出异常

问题背景

取消注释producer()中位于unique_lock作用域内的sleep调用后,代码无法按预期工作——没有任何消息输出;但将该sleep移出锁的作用域,代码就能正常每秒生成并打印消息。

预期与异常现象

  • 预期行为:producer()每秒生成一条新消息存入data,consumer()实时打印该消息
  • 异常现象:取消注释锁内sleep后,程序无任何输出,完全不执行消息打印逻辑

原代码

#include <atomic>
#include <condition_variable>
#include <iostream>
#include <mutex>
#include <ratio>
#include <string>
#include <thread>
#include <queue>

std::string data;
std::atomic<bool> ready;
std::condition_variable cv;
std::mutex m;

void producer()
{
    int c{};
    while (true)
    {
        ++c;
        {
            std::unique_lock<std::mutex> lock{ m };
            data = "count: " + std::to_string(c);
            // std::this_thread::sleep_for(std::chrono::seconds{ 1 }); // THIS LINE
            ready = true;
        }
        cv.notify_one();
    }
}

void consumer()
{
    while (true)
    {
        std::unique_lock<std::mutex> lock{ m };
        cv.wait(lock, []{ return ready == true; });
        std::cout << data << '\n';
        ready = false;
    }
}

int main()
{
    std::thread tp{ producer };
    std::thread tc{ consumer };

    tp.join();
    tc.join();
}

核心原因分析

1. 锁被长时间持有,consumer无法获取锁执行条件检查

当sleep放在unique_lock的作用域内时,producer线程会持续持有互斥锁m达1秒。此时consumer线程在执行cv.wait(lock, ...)时,第一步就需要获取互斥锁m,但锁被producer死死占用,导致consumer根本无法进入条件变量的等待逻辑,更没法检查ready状态。

2. 通知时机与线程执行节奏不匹配,出现通知丢失

producer每次循环都会在释放锁后调用cv.notify_one(),但此时consumer还在等待获取锁,无法响应这个通知。等producer的sleep结束、释放锁后,consumer终于拿到锁,这时候producer已经进入下一轮循环,又重新获取了锁并开始sleep——consumer检查ready时,可能刚把上一轮的ready设为false,而新的ready还没被设置,条件不满足,consumer再次进入等待,但此时producer的notify_one()已经发过了,导致通知丢失,consumer永远等不到有效的唤醒信号。

3. 移出锁作用域后正常的逻辑

把sleep放到unique_lock代码块外面,意味着producer更新完data和ready后会立即释放锁。此时consumer可以马上获取锁,检查到ready为true,打印消息并将ready设为false。之后producer才开始sleep,这时候锁处于释放状态,consumer可以正常进入cv.wait()等待下一次通知,两者的同步节奏完全匹配,逻辑通顺。

内容的提问来源于stack exchange,提问作者Jasper1378

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 22:10:35