生产者-消费者问题(计算机系统中的许多问题都可归结为此问题)描述如下:生产者与消费者可以通过一个环形缓冲池联系起来,环形缓冲池由几个大小相等的缓冲块组成,每个缓冲块容纳一个产品。每个生产者可不断地每次往缓冲池中送一个生产产品,而每个消费者则可不断地每次从缓冲池中取出一个产品。 编写程序模拟多个生产者和多个消费者共享缓冲池的生产和消费过程。 要求: 1. 设计信号量用于进行生产者-消费者、生产者-生产者、消费者-消费者之间的同步控制; 2. 创建多个(不少于5个)进程或者线程模拟生产者和消费者; 3. 缓冲池大小定义在10-20,缓冲块中的产品为数据; 4. 程序运行结果能实时显示缓冲池中生产和消费产品的过程,包括断点、推进时间、次序等,编程语言可选用C、C++、Java或者Python。
时间: 2024-02-13 08:07:09 浏览: 59
这是一个典型的生产者消费者问题,可以使用信号量来实现同步控制。我给您提供一个C++的示例代码:
```
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <queue>
#include <chrono>
using namespace std;
const int BUFFER_SIZE = 10; // 缓冲池大小
queue<int> buffer; // 缓冲池,存储产品
mutex mtx; // 互斥锁,保证多线程下缓冲池的安全访问
condition_variable not_full; // 缓冲池未满的条件变量
condition_variable not_empty; // 缓冲池非空的条件变量
int product_id = 0; // 产品编号
void producer(int id) {
while (true) {
// 生产产品
unique_lock<mutex> lock(mtx);
not_full.wait(lock, []{ return buffer.size() < BUFFER_SIZE; }); // 等待缓冲池未满
buffer.push(++product_id);
cout << "Producer " << id << " produced product " << product_id << ", buffer size: " << buffer.size() << endl;
lock.unlock();
not_empty.notify_all(); // 通知消费者缓冲池非空
// 休眠随机时间,模拟生产的不确定性
int sleep_time = rand() % 1000 + 500;
this_thread::sleep_for(chrono::milliseconds(sleep_time));
}
}
void consumer(int id) {
while (true) {
// 消费产品
unique_lock<mutex> lock(mtx);
not_empty.wait(lock, []{ return !buffer.empty(); }); // 等待缓冲池非空
int product = buffer.front();
buffer.pop();
cout << "Consumer " << id << " consumed product " << product << ", buffer size: " << buffer.size() << endl;
lock.unlock();
not_full.notify_all(); // 通知生产者缓冲池未满
// 休眠随机时间,模拟消费的不确定性
int sleep_time = rand() % 1000 + 500;
this_thread::sleep_for(chrono::milliseconds(sleep_time));
}
}
int main() {
srand(time(NULL));
// 创建5个生产者线程和5个消费者线程
const int NUM_PRODUCERS = 5;
const int NUM_CONSUMERS = 5;
thread producers[NUM_PRODUCERS];
thread consumers[NUM_CONSUMERS];
for (int i = 0; i < NUM_PRODUCERS; ++i) {
producers[i] = thread(producer, i+1);
}
for (int i = 0; i < NUM_CONSUMERS; ++i) {
consumers[i] = thread(consumer, i+1);
}
// 等待所有线程结束
for (int i = 0; i < NUM_PRODUCERS; ++i) {
producers[i].join();
}
for (int i = 0; i < NUM_CONSUMERS; ++i) {
consumers[i].join();
}
return 0;
}
```
该示例代码中使用了互斥锁和条件变量来实现生产者和消费者的同步控制。其中not_full和not_empty分别是缓冲池未满和非空的条件变量,用于生产者和消费者之间的通信。
在程序运行过程中,可以看到缓冲池中产品的生产和消费过程,包括产品编号、生产者编号、消费者编号以及缓冲池当前的大小等信息。
阅读全文