参考教材中的生产者消费者算法,创建5个进程,其中两个进程为生产者进程,3个进程为消费者进程。一个生产者进程试图不断地在一个缓冲中写入大写字母,另一个生产者进程试图不断地在缓冲中写入小写字母。3个消费者不断地从缓冲中读取一个字符并输出。为了使得程序的输出易于看到结果,仿照的实例程序,分别在生产者和消费者进程的合适的位置加入一些随机睡眠时间。使用C++
时间: 2024-01-21 17:17:28 浏览: 42
以下是一个基于互斥锁和条件变量的生产者-消费者模型的实现,其中包括两个生产者进程和三个消费者进程:
```
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <queue>
#include <chrono>
#include <random>
std::mutex mtx; // 互斥锁
std::condition_variable cv; // 条件变量
std::queue<char> buffer; // 缓冲区
const int BUFFER_SIZE = 10; // 缓冲区大小
// 生产者线程函数
void producer(char c, int sleep_time) {
std::default_random_engine generator;
std::uniform_int_distribution<int> distribution(1, 5);
while (true) {
std::unique_lock<std::mutex> lck(mtx);
while (buffer.size() == BUFFER_SIZE) { // 缓冲区满了,等待消费者
cv.wait(lck);
}
buffer.push(c); // 写入缓冲区
std::cout << "Producer " << std::this_thread::get_id() << " produced " << c << std::endl;
cv.notify_all(); // 唤醒等待线程
lck.unlock();
std::this_thread::sleep_for(std::chrono::milliseconds(distribution(generator) * sleep_time)); // 随机睡眠一段时间
}
}
// 消费者线程函数
void consumer(int sleep_time) {
std::default_random_engine generator;
std::uniform_int_distribution<int> distribution(1, 5);
while (true) {
std::unique_lock<std::mutex> lck(mtx);
while (buffer.empty()) { // 缓冲区空了,等待生产者
cv.wait(lck);
}
char c = buffer.front(); // 读出缓冲区的字符
buffer.pop();
std::cout << "Consumer " << std::this_thread::get_id() << " consumed " << c << std::endl;
cv.notify_all(); // 唤醒等待线程
lck.unlock();
std::this_thread::sleep_for(std::chrono::milliseconds(distribution(generator) * sleep_time)); // 随机睡眠一段时间
}
}
int main() {
std::thread t1(producer, 'A', 1000); // 生产者1写入大写字母
std::thread t2(producer, 'a', 500); // 生产者2写入小写字母
std::thread t3(consumer, 800); // 消费者1
std::thread t4(consumer, 1000); // 消费者2
std::thread t5(consumer, 1200); // 消费者3
t1.join();
t2.join();
t3.join();
t4.join();
t5.join();
return 0;
}
```
在上面的代码中,生产者线程函数 `producer` 接收两个参数:一个字符 `c` 和一个睡眠时间 `sleep_time`。生产者线程不断地向缓冲区写入字符 `c`,如果缓冲区已经满了,则等待条件变量 `cv`。当缓冲区有空位时,生产者线程将字符写入缓冲区,并输出一条消息,然后唤醒所有等待线程。最后,线程随机睡眠一段时间,以便其他线程有机会运行。
消费者线程函数 `consumer` 接收一个睡眠时间 `sleep_time`。消费者线程不断地从缓冲区读取字符,如果缓冲区已经空了,则等待条件变量 `cv`。当缓冲区有字符时,消费者线程将字符读出并输出一条消息,然后唤醒所有等待线程。最后,线程随机睡眠一段时间,以便其他线程有机会运行。
在主函数中,我们创建了两个生产者线程和三个消费者线程,并使用 `join` 函数等待它们全部运行结束。
相关推荐
![cpp](https://img-home.csdnimg.cn/images/20210720083646.png)
![rar](https://img-home.csdnimg.cn/images/20210720083606.png)
![rar](https://img-home.csdnimg.cn/images/20210720083606.png)
![-](https://csdnimg.cn/download_wenku/file_type_lunwen.png)
![-](https://csdnimg.cn/download_wenku/file_type_column_c1.png)
![-](https://csdnimg.cn/download_wenku/file_type_column_c1.png)
![-](https://csdnimg.cn/download_wenku/file_type_column_c1.png)
![-](https://csdnimg.cn/download_wenku/file_type_column_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![-](https://csdnimg.cn/download_wenku/file_type_column_c1.png)
![-](https://csdnimg.cn/download_wenku/file_type_column_c1.png)
![-](https://csdnimg.cn/download_wenku/file_type_lunwen.png)
![-](https://csdnimg.cn/download_wenku/file_type_column_c1.png)
![-](https://csdnimg.cn/download_wenku/file_type_lunwen.png)
![-](https://csdnimg.cn/download_wenku/file_type_lunwen.png)
![-](https://csdnimg.cn/download_wenku/file_type_lunwen.png)