新闻中心

C++如何实现生产者消费者模式_C++多线程同步与互斥经典案例

2025-11-26
浏览次数:
返回列表
生产者消费者模式通过共享缓冲区、互斥锁和条件变量实现多线程同步,解决数据生产与消费速度不匹配问题,C++中利用queue、mutex和condition_variable完成线程间协调,确保线程安全与高效通信。

c++如何实现生产者消费者模式_c++多线程同步与互斥经典案例

生产者消费者模式是多线程编程中的经典问题,用于解决生产数据与消费数据速度不匹配的问题。在C++中,通常使用互斥锁(std::mutex)、条件变量(std::condition_variable)和队列(std::queue)来实现线程间的同步与互斥。

核心组件说明

要实现生产者消费者模型,需要以下几个关键元素:

  • 共享缓冲区:通常是一个队列,用于暂存生产者生成的数据,供消费者取出处理。
  • 互斥锁(mutex):保护共享资源,防止多个线程同时访问导致数据竞争。
  • 条件变量(condition_variable):用于线程间通信,当缓冲区为空时让消费者等待,当缓冲区有数据时通知消费者;当缓冲区满时让生产者等待,有空间时通知生产者。

代码实现示例

下面是一个基于固定大小缓冲区的生产者消费者模型实现:

#include <iostream>
#include <thread>
#include <queue>
#include <mutex>
#include <condition_variable>
#include <chrono>

std::queue<int> buffer;
std::mutex mtx;
std::condition_variable not_empty;
std::condition_variable not_full;
const int max_buffer_size = 5;

void producer(int id) {
    for (int i = 0; i < 10; ++i) {
        std::unique_lock<std::mutex> lock(mtx);
        not_full.wait(lock, []() { return buffer.size() < max_buffer_size; });
        
        buffer.push(i);
        std::cout << "生产者 " << id << " 生产: " << i << std::endl;
        
        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<std::mutex> lock(mtx);
        not_empty.wait(lock, []() { return !buffer.empty(); });
        
        int value = buffer.front();
        buffer.pop();
        std::cout << "消费者 " << id << " 消费: " << value << std::endl;
        
        not_full.notify_one();
        std::this_thread::sleep_for(std::chrono::milliseconds(150));
    }
}

主函数中启动多个生产者和消费者线程:

Motiff妙多 Motiff妙多

Motiff妙多是一款AI驱动的界面设计工具,定位为“AI时代设计工具”

Motiff妙多 334 查看详情 Motiff妙多
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;
}

关键点解析

该实现中几个重要细节:

  • 使用 std::unique_lock 配合条件变量,支持在等待时释放锁,并在被唤醒后重新获取。
  • 条件变量的 wait 方法接受一个谓词(lambda表达式),避免虚假唤醒问题。
  • 每次修改缓冲区后调用 notify_one() 唤醒一个等待线程,也可以使用 notify_all() 唤醒所有等待线程。
  • 通过 std::this_thread::sleep_for 模拟生产/消费耗时,使输出更清晰。

应用场景与扩展

这种模式广泛应用于任务调度、消息队列、日志处理等场景。可以根据需求进行扩展:

  • 使用循环队列或智能指针管理对象生命周期。
  • 添加停止信号(如标志位)优雅关闭线程。
  • 使用 std::shared_mutex 实现读写优化(若允许多个消费者同时读)。
  • 封装成模板类,支持不同类型的数据。

基本上就这些。掌握这个模型对理解多线程同步机制非常有帮助。

以上就是C++如何实现生产者消费者模式_C++多线程同步与互斥经典案例的详细内容,更多请关注其它相关文章!


# 如何实现  # seo项目答辩考核  # 黑帽seo批量getshell  # 昌邑优化网站公司哪家好  # 2022免费推广网站  # 渭南绍兴网站推广  # 寄生虫seo广告  # 景观作图网站推广文案  # 可靠的seo平台广告  # 北海网站建设介绍服务  # 小吃店怎么做营销和推广  # 解决方法  # 怎么做  # 重写  # c++  # 几个  # 有什么  # 是一个  # 多个  # 互斥  # 多线程  # red  # 同步机制  # stream  # ios  # ai  # 生产者消费者模式 


相关栏目: 【 科技资讯46185 】 【 网络学院92790


相关推荐: 生成rdflib自定义SPARQL函数:参数匹配与实践指南  mysql备份恢复性能优化_mysql备份恢复性能优化方法  C++如何连接MySQL数据库_C++使用Connector/C++操作MySQL数据库教程  顺丰快件物流信息 官方网站查询入口  蛙漫限时开放最深处链接_蛙漫全站漫画会员同款秒开地址  mc.js游戏直达 mc.js网页免下载版本秒进地址  三星ZFold5多任务卡顿_Samsung ZFold5流畅度提升  打开就能玩的植物大战僵尸 植物大战僵尸网页版传送门  KFC套餐升级怎么获取优惠代码_KFC套餐升级活动与优惠代码获取方法  Win11怎么设置鼠标主按键_Win11鼠标左右键功能互换  创客贴用户入口官网登录 创客贴网页版电脑版系统  圆通快递查询实时追踪 圆通物流包裹状态快速查看  QQ邮箱正确登录入口_QQ邮箱官方网站使用地址  虫虫漫画精品漫画官网_虫虫漫画精品漫画官网进入精品漫画  PyTorch模型训练效果不佳?深入剖析常见错误与调试技巧  极兔快递快件信息查询系统 极兔快递官网运单号追踪  菜鸟取件码是什么怎么查 最全查询渠道汇总  C++指针和引用有什么区别_C++内存管理核心概念深度解析  顺丰快递查询系统 官方正版查询入口  React Router 嵌套组件中 URL 重定向问题的解决方案  QQ邮箱登录首页官网地址2026 QQ邮箱官方网页入口  J*aScript打印功能_j*ascript输出控制  限制HTML日期输入框的日期选择范围  Go语言中Map值调用指针接收器方法的限制与应对  俄罗斯Yandex搜索引擎入口_Yandex官网免登录一键访问  Mac怎么锁定备忘录_Mac备忘录加密设置教程  从OpenAI API响应中高效提取生成文本  企业名称高精度匹配:N-gram方法在结构相似性分析中的应用  支付宝如何管理隐私设置_支付宝隐私保护的配置技巧  解决移动端滚动问题的overflow属性应用指南  邮政快递单号查询入口 邮政快递物流信息在线查询入口  mysql通配符支持数字匹配吗_mysql通配符能否用于数字匹配的解析  C++如何进行游戏物理模拟_使用Box2D库为C++游戏添加2D物理效果  单12V-2&#215;6实现为RTX 5090供电750W!甚至都没敢跑分  qq浏览器如何查看和导出已保存的密码 qq浏览器密码管理器数据备份教程  钉钉视频会议画面卡顿如何解决 钉钉会议画面优化方法  React Router v6 教程:构建认证保护的私有路由与重定向策略  Excel组合图表怎么做 Excel创建柱状图与折线组合图教程【图表】  Golang如何使用new_Go new分配内存机制讲解  千牛数据看板网页版_千牛数据看板网页版访问方法  Composer中的^和~符号代表什么_精通Composer版本号语义化约束  HuggingFaceEmbeddings中向量嵌入维度调整的限制与理解  使用Pandas转换并合并DataFrame:多列映射至统一结构  纯CSS与HTML网格布局的HTML精简策略:SVG与JS方案解析  在Go语言中利用后缀数组处理多字符串:实现高效文本匹配与自动补全  Golang指针如何与map组合使用_Golang map指针组合实践  Win10怎么设置静态IP地址 Win10手动配置IP地址步骤【指南】  MAC如何安全彻底地删除文件_MAC使用终端命令确保文件无法被恢复  精准捕获:如何在页面中监听除特定元素外的所有点击事件  QQ邮箱在线使用入口 QQ邮箱个人账号网页版登录 

搜索