std::condition_variable 条件变量等待延时
std::condition_variable 条件变量等待延时。
std::unique_lock<std::mutex> lock(m_mtx);
if (m_cond.wait_for(lock, std::chrono::milliseconds(10)) == std::cv_status::timeout)
{
return LT_TIMEOUT;
}
m_cond对象为条件变量 std::condition_variable m_cond;。在其他同步的地方m_cond.notify_all();一下。
大概原理: wait_for() 会临时释放锁,让其他线程有机会拿到锁运行。notify_all()或notify_one()唤醒等待的线程让条件变量重新获取锁。
notify_one():随机唤醒一个正在 wait 的线程(如果有多个线程在等待)。高效:只唤醒一个线程,减少不必要的线程切换开销。不保证顺序:具体唤醒哪个线程取决于操作系统调度(无法预测)。
notify_all():作用:唤醒所有正在 wait 的线程。特点:唤醒全部:所有等待的线程会同时竞争锁,只有一个线程能立即执行,其余线程会继续阻塞。可能更慢:大量线程被唤醒可能导致“惊群效应”(thundering herd problem),增加锁竞争。
wait_for 重载版本
std::condition_variable::wait_for 有几个重载版本,它们的返回值有所不同,具体取决于是否使用谓词(Predicate)。以下是详细说明:
1. 不带谓词的重载(返回 std::cv_status)
template <class Rep, class Period>
std::cv_status wait_for(
std::unique_lock<std::mutex>& lock,
const std::chrono::duration<Rep, Period>& rel_time
);
返回值:
std::cv_status::no_timeout
表示在超时前收到了通知(通过 notify_one() 或 notify_all())。
std::cv_status::timeout
表示在指定的时间内未收到通知,因超时返回。
示例:
std::unique_lock<std::mutex> lock(mtx);
auto status = cv.wait_for(lock, std::chrono::seconds(2));
if (status == std::cv_status::timeout) {
std::cout << "Timeout occurred!\n";
} else {
std::cout << "Notified before timeout!\n";
}
2. 带谓词的重载(返回 bool)
template <class Rep, class Period, class Predicate>
bool wait_for(
std::unique_lock<std::mutex>& lock,
const std::chrono::duration<Rep, Period>& rel_time,
Predicate pred
);
返回值:
true
谓词 pred 在超时前返回 true(条件满足)。
false
超时发生,且谓词 pred 仍为 false。
注意:
该版本等价于:
while (!pred()) {
if (wait_for(lock, rel_time) == std::cv_status::timeout) {
return pred(); // 超时后再次检查谓词
}
}
return true;
即使超时,也会在返回前再次检查谓词,避免错过状态变化。
浙公网安备 33010602011771号