std::condition_variable
是另外一种重要的线程同步机制,用于在多个线程之间进行通信。
它允许一个或多个线程等待某个条件成立,并在条件成立时被唤醒。
std::condition_variable
通常与互斥量(std::mutex
)结合使用,用来保护共享数据并同步线程执行。
使用std::condition_variable
使用std::condition_variable
的基本步骤如下:
- 定义一个
std::condition_variable
对象:它是等待和通知机制的核心。 - 定义一个互斥量:用于保护共享数据和
condition_variable
的正确使用。 - 等待条件:线程通过调用
std::condition_variable
的wait()
、wait_for()
或wait_until()
成员函数等待某个条件成立。在等待期间,互斥量会被释放,以允许其他线程修改共享数据并通知等待的线程。 - 通知等待的线程:当条件成立时,可以通过调用
notify_one()
或notify_all()
成员函数来唤醒一个或所有等待的线程。
示例代码
下面的示例演示了如何使用std::condition_variable
来实现一个线程安全的生产者-消费者模式。
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <queue>
std::mutex mtx; // 互斥量,保护共享数据
std::condition_variable cv; // 条件变量
std::queue<int> dataQueue; // 一个简单的数据队列
// 生产者函数
void producer(int id) {
for (int i = 0; i < 5; ++i) {
std::unique_lock<std::mutex> lock(mtx);
dataQueue.push(i);
std::cout << "Producer " << id << " produced " << i << std::endl;
cv.notify_one(); // 通知一个等待的消费者
lock.unlock();
std::this_thread::sleep_for(std::chrono::milliseconds(100)); // 模拟生产耗时
}
}
// 消费者函数
void consumer(int id) {
while (true) {
std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock, []{ return !dataQueue.empty(); }); // 等待直到队列非空
int data = dataQueue.front();
dataQueue.pop();
std::cout << "Consumer " << id << " consumed " << data << std::endl;
lock.unlock();
if (data == 4) break; // 假设当消费到数据4时结束消费
}
}
int main() {
std::thread t1(producer, 1);
std::thread t2(consumer, 1);
t1.join();
t2.join();
return 0;
}
输出:
Producer 1 produced 0
Consumer 1 consumed 0
Producer 1 produced 1
Consumer 1 consumed 1
Producer 1 produced 2
Consumer 1 consumed 2
Producer 1 produced 3
Consumer 1 consumed 3
Producer 1 produced 4
Consumer 1 consumed 4
在这个例子中,生产者线程生产数据,并将数据放入队列,消费者线程从队列中取出数据并消费。
生产者通过notify_one()
唤醒一个正在等待的消费者线程,而消费者线程在数据队列为空时通过wait()
等待。这里使用了std::unique_lock
来自动管理互斥量的锁定和解锁。
总结
std::condition_variable
为C++提供了一种强大的线程同步机制,特别适用于需要等待特定条件成立的场景。