跳到主要内容
版本:Next

condition_variable

std::condition_variable 是 C++11 提供的条件变量,用于在线程间实现"等待-通知"机制。它允许多个线程在某个条件满足前阻塞等待,并由另一个线程在条件满足时唤醒它们。

条件变量必须配合 std::mutexstd::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()唤醒所有等待线程

使用注意

  1. 始终用带谓词的 wait(lock, pred),避免虚假唤醒导致逻辑错误。
  2. notify_one() 不保证哪个线程被唤醒,只保证至少唤醒一个。
  3. 条件变量必须在 lock 持有期间调用 wait(),内部会在等待时释放锁。
  4. 如果生产者比消费者先 notify,没人等待时 notify 会丢失,这是正常的——用队列这类中间状态解决。

小结

std::condition_variable 是 C++11 多线程的等待/通知原语,解决了"线程 B 等待线程 A 的状态变化"这一通用问题。配合 mutex + unique_lock,足以实现生产者-消费者、线程池、栅栏等常见并发模型。