std::unique_lock是condition_variable::wait唯一支持的锁类型,因wait需临时释放并重获锁;必须用while循环检查谓词防虚假唤醒;notify须与wait共用同一mutex且在修改条件后调用。

std::unique_lock 必须配合 std::condition_variable::wait 使用
直接传 std::lock_guard 给 wait() 会编译失败——wait() 要求锁对象支持移动和临时释放,而 std::lock_guard 不可复制也不可移动,且不提供 unlock()/lock() 接口。std::unique_lock 是唯一被标准明确要求支持的锁类型。
wait() 内部会自动 unlock + 阻塞 + 重新 lock
调用 cv.wait(lock, pred) 时,std::condition_variable 会先调用 lock.unlock(),再挂起线程;被唤醒后、返回前,它一定会再次调用 lock.lock()。这意味着:
-
lock在wait()返回时一定是已上锁状态,且与调用前是同一个互斥体 - 你不能在
wait()前手动unlock(),否则行为未定义 - 也不能在
wait()后假设锁仍被持有——它可能刚被唤醒又立刻被其他线程抢走(但wait()返回时一定已重锁)
必须用 while 循环检查谓词,不能用 if
虚假唤醒(spurious wakeup)是 POSIX 和 C++ 标准允许的行为:wait() 可能在没有 notify_one()/notify_all() 的情况下返回。所以必须用 while 而非 if:
std::unique_lock<std::mutex> lock(mtx);
while (!data_ready) { // ✅ 正确:循环检查
cv.wait(lock);
}
// 此时 data_ready 为 true,且 mtx 已锁
如果写成 if (data_ready) cv.wait(lock),一旦发生虚假唤醒,就会跳过条件检查,读到无效数据。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
立即学习“C++免费学习笔记(深入)”;
notify 时机要早于 wait 返回,但不必早于 wait 调用
notify_one() 或 notify_all() 可以在等待线程进入阻塞状态前、中、后任意时刻调用,只要发生在同一条件变量和互斥体上下文中即可。但要注意:
- notify 和 wait 必须使用同一个
std::mutex实例保护共享状态(比如data_ready) - notify 本身不需要锁住互斥体,但修改被等待的条件(如设置
data_ready = true)必须在锁内完成 - 典型顺序是:
lock→ 修改条件 →notify_xxx()→unlock()
漏掉对共享变量的保护,或 notify 后不 unlock,都可能导致等待线程永远卡住或读到撕裂值。

















