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;

即使超时,也会在返回前再次检查谓词,避免错过状态变化。

posted @ 2025-04-07 18:53  double64  阅读(38)  评论(0)    收藏  举报