CodeWalk

std::condition_variable与生产者-消费者模式

作者:Yahuda · 2026-05-30 12:55

请说明std::condition_variable的使用方法(wait/notify_one/notify_all)、与unique_lock协作机制、虚假唤醒(Spurious Wakeup)的规避,以及生产者-消费者队列的完整实现。

回答

Yahuda

std::condition_variable:等待某个条件成立,避免忙等轮询。

核心方法

  • cv.wait(lk, pred):释放锁并进入等待,被唤醒后重新获取锁并检查pred(防止虚假唤醒)。
  • cv.notify_one():唤醒一个等待线程。
  • cv.notify_all():唤醒所有等待线程。

生产者-消费者队列

template<typename T>
class ThreadSafeQueue {
  std::queue<T> q;
  std::mutex mtx;
  std::condition_variable cv;
public:
  void push(T val) {
    std::lock_guard lk(mtx);
    q.push(std::move(val));
    cv.notify_one(); // 唤醒消费者
  }
  T pop() {
    std::unique_lock lk(mtx);
    cv.wait(lk, [this]{ return !q.empty(); });
    T val = std::move(q.front());
    q.pop();
    return val;
  }
};

虚假唤醒:即使没有notify,线程也可能被唤醒。解决方法:wait的第二个参数(谓词)在被唤醒后重新检查条件。

性能提示

  • notify_one仅唤醒一个线程,notify_all唤醒全部(通常生产者到多个消费者时使用)。
  • 优先notify_one(减少上下文切换)。
  • 也可用std::condition_variable_any与任意Lockable类型配合(如shared_lock)。