✅ 简介
std::condition_variable
是 C++11 引入的线程间通信机制,允许线程在某个条件满足时被唤醒。- 通常与
std::mutex
一起配合使用,用于实现生产者-消费者模型、线程等待任务等场景。
🔄 基本原理
- 一个线程调用
wait()
进入阻塞状态,直到另一个线程调用 notify_one()
或 notify_all()
。 wait()
会自动释放传入的 mutex
,并在被唤醒时重新获取锁。
⚠️ 虚假唤醒(Spurious Wakeup)
🔧 使用方式
示例:生产者-消费者模型(含虚假唤醒处理)
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <queue>
#include <atomic>
#include <csignal>
#include <chrono>
std::mutex mtx;
std::condition_variable cv;
std::queue<int> dataQueue;
std::atomic<bool> stop{false};
void signalHandler(int signum) {
stop = true;
cv.notify_all();
}
void producer() {
int i = 0;
while (!stop) {
{
std::unique_lock<std::mutex> lock(mtx);
dataQueue.push(i);
std::cout << "Produced: " << i << std::endl;
++i;
}
cv.notify_one();
std::this_thread::sleep_for(std::chrono::seconds(1));
}
cv.notify_all();
}
void consumer() {
while (true) {
std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock, [] { return !dataQueue.empty() || stop; });
if (!dataQueue.empty()) {
std::cout << "Consumed: " << dataQueue.front() << std::endl;
dataQueue.pop();
lock.unlock();
std::this_thread::sleep_for(std::chrono::seconds(1));
} else if (stop) {
break;
}
}
}
int main() {
std::signal(SIGINT, signalHandler);
std::thread t1(producer);
std::thread t2(consumer);
t1.join();
t2.join();
return 0;
}
☑️ 关键函数说明
函数名 | 说明 |
---|
wait(lock) | 等待并释放锁,直到 notify_one 被调用。⚠️ 可能发生虚假唤醒。 |
wait(lock, predicate) | 带条件的等待,直到 predicate 返回 true。✅ 推荐用法 |
notify_one() | 唤醒一个等待的线程。 |
notify_all() | 唤醒所有等待的线程。 |
📌 总结
特性 | 描述 |
---|
同步机制 | 用于线程之间的通信 |
等待效率 | 阻塞等待,不占用 CPU |
虚假唤醒 | 可能无通知就被唤醒,需使用谓词保护 |
适用场景 | 生产者-消费者、线程池任务调度等 |
配套使用 | std::mutex + std::unique_lock 配合 |