- 条件变量初始化:
在C++中,使用
<condition_variable>
库。首先声明一个std::condition_variable
对象,例如:
#include <condition_variable>
#include <mutex>
#include <queue>
std::condition_variable cv;
std::mutex mtx;
std::queue<int> buffer;
const int buffer_size = 5;
- 生产者线程:
- 生产者在往缓冲区放入数据前,先获取互斥锁。
- 检查缓冲区是否已满,如果满了,则通过
cv.wait
等待条件变量。在等待过程中,互斥锁会被自动释放,当条件变量被通知时,互斥锁会被重新获取。
- 当缓冲区有空间时,放入数据,然后通知消费者线程(
cv.notify_one()
或cv.notify_all()
)。
void producer() {
int data = 0;
while (true) {
std::unique_lock<std::mutex> lock(mtx);
while (buffer.size() == buffer_size) {
cv.wait(lock);
}
buffer.push(data++);
lock.unlock();
cv.notify_one();
}
}
- 消费者线程:
- 消费者在从缓冲区取出数据前,先获取互斥锁。
- 检查缓冲区是否为空,如果空了,则通过
cv.wait
等待条件变量。同样,等待过程中互斥锁会被释放,通知时重新获取。
- 当缓冲区有数据时,取出数据进行处理,然后通知生产者线程(
cv.notify_one()
或cv.notify_all()
)。
void consumer() {
while (true) {
std::unique_lock<std::mutex> lock(mtx);
while (buffer.empty()) {
cv.wait(lock);
}
int data = buffer.front();
buffer.pop();
lock.unlock();
// 处理数据
cv.notify_one();
}
}
- 互斥锁的作用:
- 互斥锁用于保护共享资源(这里是缓冲区),防止多个线程同时访问缓冲区,避免数据竞争和不一致。
- 条件变量的
wait
操作需要一个已锁定的互斥锁,在等待过程中,互斥锁会被自动释放,这样其他线程才有机会修改共享资源(如生产者往缓冲区放数据,消费者从缓冲区取数据)。当条件变量被通知时,wait
函数重新获取互斥锁,确保后续对共享资源的操作是安全的。