当前位置: 首页 > news >正文

C++实现生产者消费者模型

生产者-消费者模型是一种典型的多线程并发模式,常用于在一个共享缓冲区中协调生产者和消费者之间的数据传递。在C++中,我们可以使用标准库中的线程、互斥量和条件变量来实现该模型。以下是一个简单的生产者-消费者模型的实现示例:

#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <queue>
#include <vector>// 定义缓冲区容量
const int BUFFER_SIZE = 10;// 缓冲区
std::queue<int> buffer;// 互斥量和条件变量
std::mutex mtx;
std::condition_variable cv_producer, cv_consumer;// 生产者函数
void producer(int id, int num_items) {for (int i = 0; i < num_items; ++i) {std::unique_lock<std::mutex> lock(mtx);// 如果缓冲区满了,等待消费者消费cv_producer.wait(lock, [] { return buffer.size() < BUFFER_SIZE; });// 生产一个项目buffer.push(i);std::cout << "Producer " << id << " produced " << i << std::endl;// 通知消费者cv_consumer.notify_one();}
}// 消费者函数
void consumer(int id, int num_items) {for (int i = 0; i < num_items; ++i) {std::unique_lock<std::mutex> lock(mtx);// 如果缓冲区为空,等待生产者生产cv_consumer.wait(lock, [] { return !buffer.empty(); });// 消费一个项目int item = buffer.front();buffer.pop();std::cout << "Consumer " << id << " consumed " << item << std::endl;// 通知生产者cv_producer.notify_one();}
}int main() {const int num_producers = 3;const int num_consumers = 3;const int num_items = 20;// 创建生产者和消费者线程std::vector<std::thread> producers, consumers;for (int i = 0; i < num_producers; ++i) {producers.emplace_back(producer, i, num_items);}for (int i = 0; i < num_consumers; ++i) {consumers.emplace_back(consumer, i, num_items);}// 等待所有线程完成for (auto& p : producers) {p.join();}for (auto& c : consumers) {c.join();}return 0;
}

代码解析

  1. 缓冲区:使用std::queue<int>来模拟缓冲区。
  2. 互斥量和条件变量:使用std::mutex来保护缓冲区的访问权,使用两个std::condition_variable来协调生产者和消费者。
  3. 生产者函数:生产者在缓冲区未满时生产数据,并通知消费者。有一个循环生产指定数量的项目。
  4. 消费者函数:消费者在缓冲区非空时消费数据,并通知生产者。有一个循环消费指定数量的项目。
  5. 主函数:创建多个生产者和消费者线程,并等待它们完成。

这个示例展示了如何使用C++标准库中的线程、互斥量和条件变量来实现一个基本的生产者-消费者模型。可以根据具体需求调整缓冲区的容量、生产者和消费者的数量以及生产和消费的项目数量。

http://www.lryc.cn/news/356556.html

相关文章:

  • 【Mac】MWeb Pro(好用的markdown编辑器) v4.5.9中文版安装教程
  • C++ | Leetcode C++题解之第118题杨辉三角
  • 3D透视图转的时候模型闪动怎么解决?---模大狮模型网
  • 如何创建一个vue项目?详细教程,如何创建第一个vue项目?
  • AWS迁移与传输之Migration Hub
  • 网络渗透思考
  • 2.8万字总结:金融核心系统数据库升级路径与场景实践
  • Linux:进程控制(二.详细讲解进程程序替换)
  • Elasticsearch8.13.4版本的Docker启动关闭HTTPS
  • linux 之dma_buf (8)- ION简化版本
  • ⌈ 传知代码 ⌋ 高速公路车辆速度检测软件
  • scrapy 整合 mitm
  • linux大文件切割
  • 图像分割模型LViT-- (Language meets Vision Transformer)
  • CANDela studio之CDDT与CDD
  • Java中的注解(Annotation)是什么?它们有什么用途?
  • 【CUDA】Nsight profile驱动的CUDA优化
  • 字符串的拼接
  • HIVE3.1.3+ZK+Kerberos+Ranger2.4.0高可用集群部署
  • Android ANR Trace日志阅读分析技巧
  • 前端Ajax、Axios和Fetch的用法和区别笔记
  • Android的Framework(TODO)
  • 牛客小白月赛94 EF题解
  • 大数据开发面试题【Flink篇】
  • Java技术深度解析:高级面试问题与精粹答案(二)
  • 算数运算符
  • 闲话 .NET(3):.NET Framework 的缺点
  • WPF实现简单的3D图形
  • 设计模式之创建型模式---原型模式(ProtoType)
  • git命令新建远程仓库