condition_variable
std::condition_variable 是 C++11 提供的条件变量,用于在线程间实现"等待-通知"机制。它允许多个线程在某个条件满足前阻塞等待,并由另一个线程在条件满足时唤醒它们。
条件变量必须配合 std::mutex 和 std::unique_lock 使用,是生产者-消费者模型、线程池、异步事件等模式的核心组件。
头文件与基本特征
#include <condition_variable>
| 特征 | 说明 |
|---|---|
| 角色 | 实现线程间等待/通知 |
| 搭配 | 必须配合 mutex + unique_lock |
| 通知方式 | notify_one() 唤醒一个,notify_all() 唤醒全部 |
| 等待方式 | wait() 阻塞直到被通知,wait_for() / wait_until() 带超时 |
| 虚假唤醒 | 可能存在,需要用条件谓词防护 |
基本用法:生产者-消费者
#include <condition_variable>
#include <iostream>
#include <mutex>
#include <queue>
#include <thread>
std::mutex mtx;
std::condition_variable cv;
std::queue<int> data;
void producer() {
for (int i = 0; i < 5; ++i) {
std::unique_lock<std::mutex> lock(mtx);
data.push(i);
std::cout << "produced: " << i << '\n';
lock.unlock();
cv.notify_one();
}
}
void consumer() {
for (int i = 0; i < 5; ++i) {
std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock, [] { return !data.empty(); });
int val = data.front();
data.pop();
lock.unlock();
std::cout << "consumed: " << val << '\n';
}
}
int main() {
std::thread t1(producer);
std::thread t2(consumer);
t1.join();
t2.join();
return 0;
}
常用接口
| 接口 | 作用 |
|---|---|
wait(lock) | 阻塞,直到被通知 |
wait(lock, pred) | 带谓词等待,防止虚假唤醒 |
wait_for(lock, duration, pred) | 等待一段时间 |
wait_until(lock, time_point, pred) | 等到指定时间点 |
notify_one() | 唤醒一个等待线程 |
notify_all() | 唤醒所有等待线程 |
使用注意
- 始终用带谓词的
wait(lock, pred),避免虚假唤醒导致逻辑错误。 notify_one()不保证哪个线程被唤醒,只保证至少唤醒一个。- 条件变量必须在 lock 持有期间调用
wait(),内部会在等待时释放锁。 - 如果生产者比消费者先
notify,没人等待时 notify 会丢失,这是正常的——用队列这类中间状态解决。
小结
std::condition_variable 是 C++11 多线程的等待/通知原语,解决了"线程 B 等待线程 A 的状态变化"这一通用问题。配合 mutex + unique_lock,足以实现生产者-消费者、线程池、栅栏等常见并发模型。