std::condition_variable与生产者-消费者模式
请说明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)。