wait必须用while循环或谓词防虚假唤醒;wait_for可带超时和谓词,超时后仍持锁,返回bool或cv_status;谓词仅在唤醒后执行,不轮询;时钟精度影响实际等待时长。

wait 会一直等下去,除非被 notify 或发生虚假唤醒;wait_for 至少会在指定时间后返回,不管有没有被 notify。
wait 不带超时,必须配合 while 或谓词使用
调用 wait 后,线程释放锁、挂起,直到被 notify_one 或 notify_all 唤醒 —— 但唤醒不等于条件满足。操作系统可能“假唤醒”,所以不能用 if 判断后直接往下走。
- 错误写法:
if (!condition) cv.wait(lock);→ 可能跳过检查、读到脏数据 - 正确做法:必须用
while (!condition) cv.wait(lock);或直接传谓词cv.wait(lock, []{ return condition; }); - 传谓词版本是语法糖,内部自动展开为 while 循环,防虚假唤醒由标准库保证
wait_for 返回状态,需显式判断超时还是被唤醒
wait_for 接收一个 std::chrono::duration(如 100ms),返回 std::cv_status 枚举值:cv_status::no_timeout 或 cv_status::timeout。它不自动重试,也不隐含条件检查。
- 只传时间参数(无谓词):返回
cv_status,你得自己再检查条件是否成立 - 传时间 + 谓词(推荐):
cv.wait_for(lock, 500ms, []{ return !queue.empty(); });→ 返回bool,true表示条件满足,false表示超时且条件仍为假 - 注意:即使超时返回
false,锁仍处于 locked 状态,可继续操作或重试
wait_for 的时钟精度和系统调度影响实际等待时长
wait_for 底层依赖系统时钟和调度器,实际等待时间往往比指定值更长 —— 尤其在高负载或低优先级线程场景下。
- 不要假设
wait_for(lock, 1ms)一定在 1ms 内返回;它只是“至少等待 1ms”,上限不可控 - 对实时性要求高的场景(如音视频同步),别依赖
wait_for做精确定时,应结合 busy-wait 或专用实时调度机制 -
steady_clock是默认时钟,不受系统时间调整影响;避免用system_clock做超时,否则 NTP 校时可能导致意外提前唤醒
容易忽略的坑:wait_for 和 wait_until 的谓词执行时机
无论 wait_for 还是 wait_until,谓词只在每次被唤醒后执行 —— 包括虚假唤醒、notify、超时三种情况。但超时本身不会触发谓词调用,只有“唤醒后”才会。
- 也就是说:超时后线程恢复执行,然后立即调用谓词一次;如果此时条件不满足,函数直接返回
false - 不会在等待过程中轮询谓词,也不会在超时前最后一刻再查一次
- 如果你需要“等待期间定期检查条件”,得自己加循环 +
sleep_for,而不是依赖wait_for
真正麻烦的不是选哪个函数,而是弄清“谁负责检查条件”和“谁负责处理超时”。传谓词的 wait_for 把这两件事打包了,但一旦逻辑变复杂(比如要记录超时次数、切换等待策略),就得拆开手动控制 —— 那时 wait_for 返回的 cv_status 和锁的状态就特别关键。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











