一、引言
在多线程编程中,经常会有进程之间相互依赖的情况,最典型的情况就是生产者消费者模型。
二、条件变量
如果线程 A 的部分代码的执行需要依赖于线程 B 中的代码,线程 A 就需要等待线程 B 执行了被依赖的代码之后才可以执行,所以线程 A 需要一种方法可以在线程 B 中的代码执行完成后得到通知。这时就可以使用条件变量。
以生产者消费者模型为例
1
2
3
4
using namespace std;
condition_variable cond; // 全局定义或者类内定义
mutex mtx; // 需要配合互斥量
queue<int> goods;
线程 A:消费者
unique_lock<mutex> lock(mtx);// 商品队列是共享资源,同时只能有一个线程访问,所以需要加锁
while (true) {
if (goods.empty()) {
cond.wait(lock); // 进入等待状态,等待的过程会释放互斥锁,以便于生产者可以生产商品
} else {
int x = goods.front();
}
}
cond.wait(lock);
进入等待状态,等待的过程会释放互斥锁,当收到通知之后会获取锁,但是获取锁不一定会成功,如果获取锁失败就会进入阻塞状态。所以复杂的场景下应注意死锁。
线程 B:生产者
1
2
3
4
5
6
7
8
while (true) {
int x = rand();
{
lock_guard<mutex> lock(mtx); // 访问时加锁,此锁生命周期结束自动释放
goods.push(x);
}
cond.notify_one();
}