C++ 标准库条件变量用法

Posted by KalosAner on March 24, 2025

一、引言

在多线程编程中,经常会有进程之间相互依赖的情况,最典型的情况就是生产者消费者模型。

二、条件变量

如果线程 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();
}