调用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的错误,有两种修正方式:
- 移除不必要的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();
- 若必须临时释放锁,需重新锁定后再调用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
相关产品推荐
相关产品推荐

