生产者消费者问题例题及详解
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
生产者消费者问题例题及详解
生产者消费者问题是一个经典的并发问题,涉及到两个独立的线程:生产者和消费者。生产者生产物品,消费者消费物品。生产者、消费者共享一个公共的固定大小的缓冲区。
以下是一个简单的生产者消费者问题的例子:
假设有一个固定大小的缓冲区,大小为N。生产者负责生成数据放入缓冲区,而消费者负责从缓冲区取出数据并处理。
1. 当缓冲区为空时,消费者被阻塞,等待生产者生产数据。
2. 当缓冲区满时,生产者被阻塞,等待消费者消费数据。
3. 缓冲区的每个元素只能被消费一次。
4. 缓冲区是循环使用的,即当缓冲区的最后一个元素被消费后,下一个元素将是缓冲区的第一个元素。
问题:如何实现这个生产者消费者模型?
解答:可以使用条件变量和互斥锁来实现这个模型。
首先,定义一个缓冲区数组和一个计数器变量来跟踪缓冲区的使用情况。然后,定义两个条件变量:一个用于生产者等待缓冲区非空,另一个用于消费者等待缓冲区非空。最后,使用互斥锁来保护对缓冲区和计数器的访问。
以下是使用C++实现的代码示例:
```cpp
include
include
include
include
const int N = 5; // 缓冲区大小
int buffer[N]; // 缓冲区数组
int count = 0; // 计数器变量,表示缓冲区的使用情况
std::mutex mutex; // 互斥锁
std::condition_variable cv_prod; // 生产者等待条件变量
std::condition_variable cv_cons; // 消费者等待条件变量
void producer() {
for (int i = 0; i < N 2; i++) {
std::unique_lock
cv_(lock, []{ return count < N; }); // 等待缓冲区非空
buffer[count] = i; // 生产数据放入缓冲区
std::cout << "Producer produced " << i << std::endl;
count++; // 更新计数器变量
if (count == N) count = 0; // 循环使用缓冲区
cv__one(); // 通知消费者消费数据
}
}
void consumer() {
for (int i = 0; i < N 2; i++) {
std::unique_lock
cv_(lock, []{ return count > 0; }); // 等待缓冲区非空
int data = buffer[count]; // 从缓冲区取出数据并处理 std::cout << "Consumer consumed " << data << std::endl;
count--; // 更新计数器变量
if (count == -1) count = N - 1; // 循环使用缓冲区
cv__one(); // 通知生产者生产数据
}
}
int main() {
std::thread prod(producer); // 创建生产者线程 std::thread cons(consumer); // 创建消费者线程 (); // 等待生产者线程结束
(); // 等待消费者线程结束
return 0;
}
```