全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

C++怎么实现生产者消费者模型_C++多线程并发模型与生产者消费者实现

生产者消费者模型通过互斥锁和条件变量实现线程安全的缓冲区共享,生产者在缓冲区未满时添加数据,消费者在非空时取出数据,配合谓词等待避免虚假唤醒,使用notify_one提升效率,可通过结束标志正常退出线程。

生产者消费者模型是多线程编程中的经典问题,用于描述多个线程之间如何安全地共享有限缓冲区的数据。C++中可以通过标准库的多线程支持()高效实现该模型。

使用互斥锁和条件变量实现生产者消费者

核心组件包括一个共享缓冲区、互斥锁保护数据访问、两个条件变量分别通知“有空位”和“有数据”。生产者在缓冲区未满时添加数据,消费者在缓冲区非空时取出数据。

以下是一个基于固定大小队列的实现示例:

#include 
#include 
#include 
#include 
#include 
#include 

std::queue buffer;
std::mutex mtx;
std::condition_variable not_full;
std::condition_variable not_empty;

const int max_size = 5;

void producer(int id) {
    for (int i = 0; i < 10; ++i) {
        std::unique_lock lock(mtx);
        not_full.wait(lock, []() { return buffer.size() < max_size; });
        buffer.push(i);
        std::cout << "Producer " << id << " produced: " << i << "\n";
        lock.unlock();
        not_empty.notify_one();
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
    }
}

void consumer(int id) {
    for (int i = 0; i < 10; ++i) {
        std::unique_lock lock(mtx);
        not_empty.wait(lock, []() { return !buffer.empty(); });
        int value = buffer.front();
        buffer.pop();
        std::cout << "Consumer " << id << " consumed: " << value << "\n";
        lock.unlock();
        not_full.notify_one();
        std::this_thread::sleep_for(std::chrono::milliseconds(150));
    }
}

在主函数中启动多个生产者和消费者线程即可观察协同工作:

int main() {
    std::thread p1(producer, 1);
    std::thread p2(producer, 2);
    std::thread c1(consumer, 1);
    std::thread c2(consumer, 2);

    p1.join();
    p2.join();
    c1.join();
    c2.join();

    return 0;
}

关键机制说明

条件变量等待必须配合谓词使用:避免虚假唤醒导致逻辑错误。例如 not_full.wait(lock, [](){ return buffer.size() 确保只有真正满足条件时才继续执行。

notify_one 与 notify_all 的选择:若只有一个等待线程需被唤醒,用 notify_one 更高效;若存在多个同类等待者,根据场景决定是否广播。

解锁后通知:先释放锁再调用 notify 可减少唤醒后立即阻塞的概率,提升性能。

可改进方向

  • 使用智能指针或自定义消息结构传递复杂数据
  • 引入结束标志位,使消费者在生产完成后续正常退出
  • 采用循环缓冲区或双缓冲技术提升吞吐量
  • 使用 std::atomic 标记运行状态,避免强制终止线程

加入结束控制的简单方式是在共享区域添加:

bool done = false;
// 消费者中检测
not_empty.wait(lock, []() { return !buffer.empty() || done; });
if (done && buffer.empty()) break;
基本上就这些。C++11以后的标准库已足够支撑健壮的生产者消费者模型,关键是正确使用锁和条件变量组合,确保线程安全与响应性。


# ai  # c++  # ios  # stream  # 数据访问  # 标准库  # 循环  # 指针  # 线程  # 多线程  # Thread  # 并发  # 多个  # 互斥  # 未满  # 是一个  # 是在  # 可以通过  # 自定义  # 只有一个  # 可通过 


相关文章: 大连网站制作公司哪家好一点,大连买房网站哪个好?  成都品牌网站制作公司,成都营业执照年报网上怎么办理?  C#如何在一个XML文件中查找并替换文本内容  制作网站怎么制作,*游戏网站怎么搭建?  北京制作网站的公司排名,北京三快科技有限公司是做什么?北京三快科技?  英语简历制作免费网站推荐,如何将简历翻译成英文?  如何在西部数码注册域名并快速搭建网站?  定制建站是什么?如何实现个性化需求?  台州网站建设制作公司,浙江手机无犯罪记录证明怎么开?  大连 网站制作,大连天途有线官网?  教学网站制作软件,学习*后期制作的网站有哪些?  网站制作专业公司有哪些,如何制作一个企业网站,建设网站的基本步骤有哪些?  c# F# 的 MailboxProcessor 和 C# 的 Actor 模型  如何快速搭建高效服务器建站系统?  做企业网站制作流程,企业网站制作基本流程有哪些?  岳西云建站教程与模板下载_一站式快速建站系统操作指南  免费视频制作网站,更新又快又好的免费电影网站?  如何在建站主机中优化服务器配置?  实现点击下箭头变上箭头来回切换的两种方法【推荐】  建站三合一如何选?哪家性价比更高?  如何在阿里云域名上完成建站全流程?  如何在Golang中使用encoding/gob序列化对象_存储和传输数据  c# await 一个已经完成的Task会发生什么  c# 在ASP.NET Core中管理和取消后台任务  建站之星客服服务时间及联系方式如何?  如何选择网络建站服务器?高效建站必看指南  香港代理服务器配置指南:高匿IP选择、跨境加速与SEO优化技巧  建站上传速度慢?如何优化加速网站加载效率?  如何制作新型网站程序文件,新型止水鱼鳞网要拆除吗?  如何在Windows 2008云服务器安全搭建网站?  定制建站模板如何实现SEO优化与智能系统配置?18字教程  如何在阿里云高效完成企业建站全流程?  php能控制zigbee模块吗_php通过串口与cc2530 zigbee通信【介绍】  公司网站建设制作费用,想建设一个属于自己的企业网站,该如何去做?  如何使用Golang安装API文档生成工具_快速生成接口文档  如何高效完成独享虚拟主机建站?  微信小程序 五星评分(包括半颗星评分)实例代码  如何将凡科建站内容保存为本地文件?  c# 在高并发下使用反射发射(Reflection.Emit)的性能  建站之星如何实现五合一智能建站与营销推广?  如何用wdcp快速搭建高效网站?  单页制作网站有哪些,朋友给我发了一个单页网站,我应该怎么修改才能把他变成自己的呢,请求高手指点迷津?  宝华建站服务条款解析:五站合一功能与SEO优化设置指南  如何安全更换建站之星模板并保留数据?  定制建站价位费用解析与套餐推荐全攻略  如何通过FTP服务器快速搭建网站?  c++怎么编写动态链接库dll_c++ __declspec(dllexport)导出与调用【方法】  建站之星安装后如何自定义网站颜色与字体?  网站网页制作电话怎么打,怎样安装和使用钉钉软件免费打电话?  黑客如何利用漏洞与弱口令入侵网站服务器? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。