新闻中心
C++如何实现生产者消费者模型_C++ condition_variable多线程同步实例
生产者消费者模型通过互斥锁和条件变量实现线程同步,生产者在缓冲区满时等待,消费者在空时等待,使用cv.wait配合谓词避免虚假唤醒,notify_all通知状态变化,确保线程安全协作。

在C++多线程编程中,生产者消费者模型是经典的线程同步问题。它描述了多个线程之间通过共享缓冲区进行协作:生产者生成数据并放入缓冲区,消费者从缓冲区取出数据处理。为了避免竞争条件和资源浪费,需要使用互斥锁和条件变量来协调线程行为。
使用std::condition_variable实现生产者消费者模型
C++11引入了std::condition_variable和std::mutex,为多线程同步提供了标准支持。核心思路是:
- 用std::mutex保护共享缓冲区,防止多个线程同时访问
- 生产者在缓冲区满时等待,消费者在缓冲区空时等待
- 使用std::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 cv; const int max_buffer_size = 5; void producer(int id) { for (int i = 0; i < 10; ++i) { std::unique_lock<std::mutex> lock(mtx); cv.wait(lock, []{ return buffer.size() < max_buffer_size; }); buffer.push(i); std::cout << "Producer " << id << " produced: " << i << std::endl; lock.unlock(); cv.notify_all(); 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); cv.wait(lock, []{ return !buffer.empty(); }); int value = buffer.front(); buffer.pop(); std::cout << "Consumer " << id << " consumed: " << value << std::endl; lock.unlock(); cv.notify_all(); std::this_thread::sleep_for(std::chrono::milliseconds(150)); } }
主函数创建两个生产者和一个消费者线程:
AdMaker AI
从0到爆款高转化AI广告生成器
65
查看详情
int main() {
std::thread p1(producer, 1);
std::thread p2(producer, 2);
std::thread c1(consumer, 1);
p1.join();
p2.join();
c1.join();
return 0;
}
关键点说明
条件变量的wait用法:cv.wait(lock, predicate)会自动释放锁并在条件不满足时阻塞,当被唤醒时重新获取锁并检查条件。这种模式避免了忙等,提高了效率。
notify_all vs notify_one:使用notify_all()可以唤醒所有等待线程,适用于多个生产者或消费者的情况。如果确定只有一个线程需要唤醒,可用notify_one()减少上下文切换开销。
虚假唤醒处理:条件变量可能发生虚假唤醒,因此wait必须配合循环或谓词使用,确保条件真正满足才继续执行。
基本上就这些。这个模型可扩展用于实际场景,比如任务队列、日志处理等,只需替换数据类型和处理逻辑即可。以上就是C++如何实现生产者消费者模型_C++ condition_variable多线程同步实例的详细内容,更多请关注其它相关文章!
# c++
# ai
# 如何实现
# 游戏开发
# 多个
# 多线程
# red
# stream
# ios
# 网站建设技术教程
# 邵武正规seo服务费
# 阜新网站推广报价
# 宝安做网站推广
# 枣庄seo公司地址
# 移动网站优化教程
# 网络推广网站制作
# 太仓高端网站建设
# 黑龙江淘宝网站建设好处
# 唐山营销推广品牌有哪些
# 适用于
# 只需
# 互斥
# 边缘
# 是一个
# 尼克
相关栏目:
【
科技资讯46185 】
【
网络学院92790 】
相关推荐:
qq浏览器如何查看和导出已保存的密码 qq浏览器密码管理器数据备份教程
sublime怎么预览Markdown渲染效果_Markdown Preview插件 for sublime教程
网站内容防复制粘贴的实现策略与局限性
漫蛙漫画官方主页入口 漫蛙MANWA网页直达访问链接
win11开机启动修复循环怎么办 Win11无法进入系统高级启动解决方法【修复】
QQ网页版官方账号入口 QQ网页版网页版登录指南
c++中的std::basic_string的SSO优化_c++短字符串优化深度解析
海棠电脑版入口_通过电脑访问海棠官网阅读
AO3官方可用镜像 Archive of Our Own网页版最新入口
在J*a中如何使用Exception包装底层异常_异常包装与信息传递方法说明
快手网页版在线登录 快手网页版官网入口快速访问
C++如何比较两个字符串_C++ string compare函数与操作符对比
神庙逃亡小游戏在线玩 神庙逃亡小游戏入口
Win11文件资源管理器卡顿怎么修 Win11重置资源管理器进程优化响应速度【修复方法】
CSS自定义字体样式被系统字体替换怎么办_font-face方式指定font-display控制渲染策略
Spring Boot内嵌服务器与J*a EE全栈特性:选择与部署策略
2025年云电脑操作系统体验 | 无需本地硬件,随时随地使用高性能PC
Python模块化编程:有效管理依赖与避免循环引用
如何在 Excel Online 和 Google 表格中更改日期格式
poki免费入口快捷访问 poki人气小游戏直接玩站点
QQ邮箱官方邮箱登录入口 QQ邮箱网页版快速访问
深入理解J*a链表中的IPosition接口与使用
漫蛙2正版漫画站 漫蛙2网页版快速访问入口
蛙漫官方正版入口 蛙漫网页在线全集免费观看
excel怎么制作工资条 excel快速生成工资条的方法
Golang如何实现简单的Web表单_Golang表单提交与验证处理方法
深入理解Go语言中Map值与方法接收器的交互:为什么需要临时变量
火锅吃太多会怎样 火锅吃太多会上火吗
CSS条件样式无法按设备触发怎么排查_media条件语句正确设置解决触发问题
HTML长属性值处理:表单action路径优化与代码规范应对
俄罗斯Yandex免登录入口_Yandex搜索引擎官网一键直达
SteamMachine定价或为699美元 大家想入手吗?
动漫共和国防屏蔽稳定域名-动漫共和国官方正版直达通道
PowerPoint如何制作滚动字幕结尾彩蛋_PowerPoint路径动画实现平滑滚动字幕效果
J*a里如何使用N*igableMap进行导航操作_可导航Map操作技巧解析
谷歌浏览器最新官方入口链接 谷歌浏览器网页版官网导航
AO3镜像入口大全 AO3网页版内容访问全集
神经网络二分类模型训练异常:高损失与完美验证准确率的排查与修正
小米14应用无法联网原因分析_小米14网络权限修复
J*aScript动态修改指定div内所有a标签样式指南
J*a递归快速排序中静态变量的状态管理与陷阱
痛风发作了怎么办? 快速止痛和后期饮食调理
Django AJAX 文件上传教程:解决图片无法保存到模型的常见问题
Lar*el Form Request中唯一性验证在更新操作中的正确实现
Win11蓝牙耳机断连怎么解决 Win11蓝牙设置重新配对与驱动更新【技巧】
在J*a中如何隐藏复杂性_使用门面模式组织对象交互
Linux如何构建多环境配置管理_Linux多环境配置方案
快速CSGO开箱网站指南 CSGO开箱平台推荐
反效果?《战地6》免费试玩开启后玩家数不升反降
新手怎么开始学化妆 零基础化妆入门教程


2025-12-07
浏览次数:次
返回列表
ffer;
std::mutex mtx;
std::condition_variable cv;
const int max_buffer_size = 5;
void producer(int id) {
for (int i = 0; i < 10; ++i) {
std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock, []{ return buffer.size() < max_buffer_size; });
buffer.push(i);
std::cout << "Producer " << id << " produced: " << i << std::endl;
lock.unlock();
cv.notify_all();
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);
cv.wait(lock, []{ return !buffer.empty(); });
int value = buffer.front();
buffer.pop();
std::cout << "Consumer " << id << " consumed: " << value << std::endl;
lock.unlock();
cv.notify_all();
std::this_thread::sleep_for(std::chrono::milliseconds(150));
}
}