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

调用std::condition_variable::wait前未锁定mutex,会自动锁定吗?

关于std::condition_variable::wait的mutex锁定要求及代码问题分析

核心问题答案

std::condition_variable的wait函数不会自动锁定未处于锁定状态的mutex,反而要求传入的std::unique_lock<std::mutex>必须处于锁定状态——这是wait的强制前置条件。违反此条件会触发未定义行为,也就是你遇到异常的直接原因。

你的代码问题分析

Part1中的错误

在Part1代码里,你在调用cv.wait前手动解锁了mutex,导致传入wait的锁处于未锁定状态:

uniqueLock.unlock(); 
CoordPlaybackMediator::GetCV().notify_one();
std::condition_variable& cv = CoordPlaybackMediator::GetCV();
cv.wait(uniqueLock, []()->bool {return CoordPlaybackMediator::GetCoordReadyFlag(); }); 

这完全违反了wait的使用规则,必然会引发未定义行为(比如程序崩溃、死锁、条件变量逻辑紊乱等)。

另外,Part1最后一行的uniqueLock.unlock()本身是合理的——因为wait被唤醒后会自动重新锁定mutex,但前面的错误调用已经破坏了整个逻辑。

Part2中的正确用法

Part2的代码符合wait的使用规范:构造uniqueLock时自动锁定mutex,直接传入wait函数,wait会自动释放mutex等待通知,被唤醒后重新锁定mutex并检查条件,整个流程合法。

修正建议

针对Part1的错误,有两种修正方式:

  1. 移除不必要的unlock调用:保留mutex锁定状态直到wait调用,这是最常规的用法:
std::mutex& mtx = CoordPlaybackMediator::GetMutex();
std::unique_lock<std::mutex> uniqueLock(mtx);
CoordPlaybackMediator::SetPlayBackReadyFlag(true);
// 移除这里的unlock
CoordPlaybackMediator::GetCV().notify_one();
std::condition_variable& cv = CoordPlaybackMediator::GetCV();
cv.wait(uniqueLock, []()->bool {return CoordPlaybackMediator::GetCoordReadyFlag(); }); 
CoordPlaybackMediator::ResetCoorAndPlayBackFlags();
uniqueLock.unlock();
  1. 若必须临时释放锁,需重新锁定后再调用wait:如果业务逻辑要求在notify后释放锁一段时间,要确保wait前重新锁定:
std::mutex& mtx = CoordPlaybackMediator::GetMutex();
std::unique_lock<std::mutex> uniqueLock(mtx);
CoordPlaybackMediator::SetPlayBackReadyFlag(true);
uniqueLock.unlock(); 
CoordPlaybackMediator::GetCV().notify_one();
// 重新锁定mutex
uniqueLock.lock();
std::condition_variable& cv = CoordPlaybackMediator::GetCV();
cv.wait(uniqueLock, []()->bool {return CoordPlaybackMediator::GetCoordReadyFlag(); }); 
CoordPlaybackMediator::ResetCoorAndPlayBackFlags();
uniqueLock.unlock();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 01:30:06