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

条件变量被通知但未持锁时的行为及示例中cv.wait的执行逻辑

条件变量收到通知但未获取锁时的行为分析

问题背景

当条件变量收到通知但尚未获取锁时会发生什么?针对以下代码,cv.wait()会执行什么逻辑?若consumer被producer通知后无法获取m_cnt锁,会无限尝试获取锁吗?

std::condition_variable cv;
std::mutex m_cnt;
int cnt = 0;
void producer() {
    std::unique_lock<std::mutex> ul(m_cnt);
    cnt++;
    cv.notify_one();
    std::this_thread::sleep_for(std::chrono::seconds(1));
}
void consumer() {
    std::unique_lock<std::mutex> ul(m_cnt);
    cv.wait(ul, [] {return cnt > 0;}); // 关注这里
    cnt--;
}

核心逻辑分析

cv.wait(ul, predicate)的完整执行流程

  1. 初始阶段:调用wait时,unique_lock已持有锁,wait会自动释放该锁,随后consumer线程进入条件变量的等待队列,阻塞等待通知。
  2. 收到通知后:consumer被唤醒,首先尝试重新获取m_cnt锁——如果此时锁被producer持有(比如示例中producer调用notify_one后仍在sleep,锁未释放),consumer不会无限循环尝试,而是进入mutex的等待队列,和其他请求该锁的线程一样,等待锁被释放。
  3. 获取锁后的检查:当producer的unique_lock析构(sleep结束后函数返回),锁被释放,consumer拿到锁后,会立即检查传入的谓词cnt > 0:
    • 如果谓词为true(示例中此时cnt=1),wait返回,consumer继续执行后续的cnt--。
    • 如果谓词为false(比如出现虚假唤醒),wait会再次释放锁,回到条件变量的等待队列,继续等待下一次通知。

针对示例的具体行为

示例中producer调用notify_one后,锁仍在自己手中,consumer收到通知后会尝试获取锁,但抢不到就进入mutex的等待队列,直到producer sleep结束、释放锁,consumer才能拿到锁,接着检查谓词并继续执行,不会出现无限尝试的情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 21:34:57