PV操作——生产者消费者问题C++代码
时间: 2023-07-30 10:06:10 浏览: 151
以下是使用C++中的线程库`<thread>`、互斥锁`std::mutex`和条件变量`std::condition_variable`实现生产者消费者问题的示例代码:
```c++
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <queue>
#include <chrono>
#include <random>
using namespace std;
// 定义生产者和消费者线程所需的数据结构
struct Data {
int id;
// 其他数据...
};
// 缓冲区大小
const int BUFFER_SIZE = 5;
// 全局变量
queue<Data> buffer; // 共享缓冲区
mutex buffer_mutex; // 互斥锁,用于同步访问缓冲区
condition_variable full_cond, empty_cond; // 条件变量,用于同步线程
// 生产者线程
void producer(int items) {
for (int i = 0; i < items; i++) {
// 创建一个新的数据
Data data{i};
// 获取互斥锁
unique_lock<mutex> lock{buffer_mutex};
// 如果缓冲区已满,则等待
while (buffer.size() == BUFFER_SIZE) {
empty_cond.wait(lock);
}
// 将数据添加到缓冲区中
buffer.push(data);
cout << "生产者添加数据 " << data.id << endl;
// 释放互斥锁
lock.unlock();
// 通知等待在full_cond条件变量上的线程
full_cond.notify_one();
// 随机等待一段时间
this_thread::sleep_for(chrono::milliseconds(rand() % 1000));
}
}
// 消费者线程
void consumer(int items) {
for (int i = 0; i < items; i++) {
// 获取互斥锁
unique_lock<mutex> lock{buffer_mutex};
// 如果缓冲区为空,则等待
while (buffer.empty()) {
full_cond.wait(lock);
}
// 从缓冲区中取出数据
Data data = buffer.front();
buffer.pop();
cout << "消费者取出数据 " << data.id << endl;
// 释放互斥锁
lock.unlock();
// 通知等待在empty_cond条件变量上的线程
empty_cond.notify_one();
// 随机等待一段时间
this_thread::sleep_for(chrono::milliseconds(rand() % 1000));
}
}
int main() {
// 生产者和消费者要处理的数据量
int items = 10;
// 创建生产者和消费者线程
thread producer_thread{producer, items};
thread consumer_thread{consumer, items};
// 等待线程结束
producer_thread.join();
consumer_thread.join();
return 0;
}
```
在这个示例代码中,我们使用了C++中的线程库`<thread>`来创建生产者和消费者线程,并且使用了互斥锁`std::mutex`和条件变量`std::condition_variable`来实现PV操作。具体来说,我们使用互斥锁来保护共享缓冲区的访问,并且使用条件变量来同步线程的执行。在生产者线程中,我们首先获取互斥锁,并且在缓冲区已满的情况下等待,然后将数据添加到缓冲区中并通知等待在full_cond条件变量上的线程。在消费者线程中,我们首先获取互斥锁,并且在缓冲区为空的情况下等待,然后从缓冲区中取出数据并通知等待在empty_cond条件变量上的线程。通过这种方式,我们可以保证生产者和消费者线程之间的同步,并且避免了数据竞争和死锁等问题。
阅读全文