新闻中心
C++ condition_variable教程_C++生产者消费者模型实现详解
condition_variable用于C++多线程同步,配合mutex实现生产者-消费者模型:生产者在缓冲区满时等待,消费者在空时等待,通过wait+谓词避免虚假唤醒,notify_all通知对应线程,确保安全高效协作。

在C++多线程编程中,condition_variable 是实现线程间同步的重要工具之一。它常用于解决生产者-消费者这类协作问题,确保多个线程在共享资源访问时能够安全、高效地协同工作。
condition_variable 基本概念
condition_variable 定义在
关键成员函数包括:
- wait(lock, predicate):释放锁并阻塞线程,直到被唤醒且谓词为真
- notify_one():唤醒一个等待的线程
- notify_all():唤醒所有等待的线程
使用 wait 时推荐传入谓词(lambda 或函数对象),避免虚假唤醒带来的问题。
生产者-消费者模型设计思路
该模型包含两类线程:
- 生产者:向共享缓冲区添加数据
- 消费者:从缓冲区取出数据处理
需要解决的问题:
- 缓冲区满时,生产者应等待
- 缓冲区空时,消费者应等待
- 对缓冲区的访问必须互斥
为此引入:
N世界
一分钟搭建会展元宇宙
138
查看详情
- 一个互斥量(mutex)保护缓冲区
- 一个 condition_variable 供生产者等待
- 另一个 condition_variable 供消费者等待
代码实现示例
以下是一个完整的 C++ 实现:
#include <iostream> #include <thread> #include <queue> #include <mutex> #include <condition_variable> #include <chrono> std::queue<int> buffer; std::mutex mtx; std::condition_variable cv_full; // 缓冲区未满 std::condition_variable cv_empty; // 缓冲区非空 const int max_size = 5; void producer(int id) { for (int i = 0; i < 10; ++i) { std::unique_lock<std::mutex> lock(mtx); cv_full.wait(lock, []{ return buffer.size() < max_size; }); buffer.push(i); std::cout << "生产者 " << id << " 生产: " << i << "\n"; lock.unlock(); cv_empty.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_empty.wait(lock, []{ return !buffer.empty(); }); int value = buffer.front(); buffer.pop(); std::cout << "消费者 " << id << " 消费: " << value << "\n"; lock.unlock(); cv_full.notify_all(); // 通知生产者可以生产 std::this_thread::sleep_for(std::chrono::milliseconds(150)); } }
main 函数启动多个生产者和消费者:
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;
}
注意事项与最佳实践
使用 condition_variable 时需注意:
- 始终使用 unique_lock
而不是 lock_guard,因为 wait 会原子性地释放锁 - wait 的谓词判断必不可少,防止虚假唤醒导致逻辑错误
- notify 后不必立即释放锁,但应尽快减少临界区范围
- 考虑使用 notify_one() 减少不必要的线程唤醒开销,除非确实需要唤醒全部等待者
在实际项目中,可将缓冲区封装成一个线程安全的类,隐藏同步细节,提高代码复用性。
基本上就这些。掌握 condition_variable 的正确用法,是写出健壮多线程程序的关键一步。
以上就是C++ condition_variable教程_C++生产者消费者模型实现详解的详细内容,更多请关注其它相关文章!
# 是一个
# 都江堰网站推广选哪家
# 泉州seo优化指南
# Wp中文seo插件
# 东莞优化网站单价
# 兄弟素材网站建设需要
# 苹果生鲜营销推广文案范文
# 长沙网站建设课程总结
# 太原网站建设市场分析
# 营销策划与推广照片
# 利通区大数据全网营销推广怎么做
# 相关文章
# 互斥
# 编解码
# 工具
# 有什么区别
# 如何使用
# 复用
# 多个
# 如何实现
# 多线程
# red
# 代码复用
# stream
# ios
# c++
# ai
相关栏目:
【
科技资讯46185 】
【
网络学院92790 】
相关推荐:
J*aScript map 迭代中检测空数组元素的有效方法
邮政编码查询不到怎么办_邮政编码查询不到的常见原因与对策
小米汽车11月交付量突破40000台!雷军:将继续努力
Vue.js 图片显示异常排查:理解应用挂载范围与DOM ID唯一性
在python-socketio事件处理器中安全访问Flask应用上下文
网易大神怎么保存别人动态的图片_网易大神动态图片保存方法
如何优雅地解决Livewire文件上传难题?SpatieLivewireFilepond让一切变得简单
解决Django多数据库/多Schema环境下外键迁移问题
Win10怎么制作U盘启动盘 Win10系统安装U盘制作教程【详解】
大象笔记网页版入口 印象笔记网页版登录入口
《噬血代码2》新预告片发布 展示游戏剧情
深入理解与实现最大堆的Heapify过程:常见错误与修正
如何创建没有密码的Windows本地账户_跳过微软账户登录的技巧【教程】
12306几点到几点不能订票? | 官方最新系统维护时间全解析
《主播少女的秘密账号迷宫》首支宣传片
一加Ace 6T支持全新明眸护眼:通过了最严苛的护眼小金标认证
如何高效处理PHP中的Excel数据导入导出?PortPHP/Spreadsheet助你轻松搞定!
Tabulator表格中精确实现日期时间排序的指南
Go语言中对Map值调用带指针接收者方法:原理与最佳实践
sublime怎么覆盖插件的默认快捷键_sublime快捷键优先级与设置
新手怎么开始学化妆 零基础化妆入门教程
vivo手机参数配置怎么增强信号_vivo手机参数配置信号增强方法
一加Ace 6T实拍样张首次公布!李杰:主摄实力完全看齐4K档性能旗舰
Pandas DataFrame:高效添加条件计算列
漫蛙manwa官网登录界面_漫蛙漫画网页版主站入口
Google翻译怎么语音输入_Google翻译语音输入功能使用与设置方法
汽车之家官方网站官网入口_汽车之家网页版直接进入
VS Code远程开发时如何处理文件权限问题
sublime怎么预览Markdown渲染效果_Markdown Preview插件 for sublime教程
c++如何实现一个简单的软件渲染器_c++从零开始的3D图形学
MAC如何将整个网页截长图_MAC使用Safari的导出为PDF或第三方工具
魅族20怎样在浏览器开无图省流_iPhone魅族20浏览器开无图省流【流量节省】
zookeeper 都有哪些功能?
CSS如何设置hover状态颜色_hover伪类调整背景或文字颜色
如何仅使用CSS更改登录界面背景图像图标的颜色
必由学官方网站入口 必由学学生教师共用登录通道
Kafka Streams中基于消息头条件过滤消息的实现指南
优化Log4j2控制台输出性能:解决异步日志瓶颈
CSS自定义字体样式被系统字体替换怎么办_font-face方式指定font-display控制渲染策略
J*aScript类型检查_j*ascript代码规范
蛙漫限时开放最深处链接_蛙漫全站漫画会员同款秒开地址
j*a toString()的覆盖
微信语音通话掉线如何解决 微信语音通话稳定优化方法
Django AJAX 文件上传教程:解决图片无法保存到模型的常见问题
树莓派传感器触发:通过Twilio API发送WhatsApp消息教程
sublime如何配置Go语言开发环境_sublime搭建Golang编译运行系统
“音游” × “怪文书” 题材的节奏冒险游戏 《晕晕电波症候群》确定于2026年4月发售!
机器学习中对数变换预测结果的反向还原
12306选座怎么选到商务座_12306商务座选择与配置说明
AO3官方可用镜像 Archive of Our Own网页版最新入口


2025-11-29
浏览次数:次
返回列表
clude <mutex>
#include <condition_variable>
#include <chrono>
std::queue<int> buffer;
std::mutex mtx;
std::condition_variable cv_full; // 缓冲区未满
std::condition_variable cv_empty; // 缓冲区非空
const int max_size = 5;
void producer(int id) {
for (int i = 0; i < 10; ++i) {
std::unique_lock<std::mutex> lock(mtx);
cv_full.wait(lock, []{ return buffer.size() < max_size; });
buffer.push(i);
std::cout << "生产者 " << id << " 生产: " << i << "\n";
lock.unlock();
cv_empty.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_empty.wait(lock, []{ return !buffer.empty(); });
int value = buffer.front();
buffer.pop();
std::cout << "消费者 " << id << " 消费: " << value << "\n";
lock.unlock();
cv_full.notify_all(); // 通知生产者可以生产
std::this_thread::sleep_for(std::chrono::milliseconds(150));
}
}