新闻中心
C++如何使用std::condition_variable_C++多线程同步与条件变量使用
std::condition_variable用于线程同步,配合std::mutex实现等待-通知机制,如生产者-消费者模型中,通过wait()阻塞线程直到条件满足,notify_one()或notify_all()唤醒线程,需用unique_lock并结合谓词防止虚假唤醒,确保正确处理共享状态。

在C++多线程编程中,std::condition_variable 是实现线程间同步的重要工具之一。它通常与 std::mutex 配合使用,用于让一个或多个线程等待某个条件成立,而另一个线程在条件满足时通知等待的线程继续执行。
基本概念:条件变量的作用
条件变量不是用来保护共享数据的,而是用来协调线程之间的执行顺序。比如生产者-消费者模型中,消费者线程需要等待缓冲区非空,而生产者在放入数据后可以通知消费者。这时就适合使用 std::condition_variable。
关键组件包括:
- std::condition_variable:提供 wait、notify_one、notify_all 接口
- std::unique_lock<:mutex>:必须配合 unique_lock 使用,不能用 lock_guard
- 共享条件判断:通常是一个布尔表达式,表示某种状态是否成立
基本用法示例:生产者-消费者模型
下面是一个简单的例子,演示如何使用条件变量实现两个线程间的协作:
#include <iostream>
#include <thread>
#include <queue>
#include <mutex>
#include <condition_variable>
std::queue<int> data_queue;
std::mutex mtx;
std::condition_variable cv;
bool finished = false;
void producer() {
for (int i = 0; i < 5; ++i) {
std::lock_guard<std::mutex> lock(mtx);
data_queue.push(i);
std::cout << "生产: " << i << "\n";
lock.unlock(); // 提前释放锁
cv.notify_one(); // 通知一个消费者
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
{
std::lock_guard<std::mutex> lock(mtx);
finished = true;
}
cv.notify_all(); // 通知所有等待线程结束
}
void consumer() {
while (true) {
std::unique_lock<std::mutex> lock(mtx);
// 条件等待:队列为空且未结束,则等待
cv.wait(lock, [] {
return !data_queue.empty() || finished;
});
if (!data_queue.empty()) {
int value = data_queue.front();
data_queue.pop();
std::cout << "消费: " << value << "\n";
}
if (data_queue.empty() && finished) {
break; // 结束循环
}
lock.unlock();
}
}
主函数启动线程:
Whimsical
Whimsical推出的AI思维导图工具
182
查看详情
int main() {
std::thread p(producer);
std::thread c(consumer);
p.join();
c.join();
return 0;
}
wait 的正确使用方式
cv.wait() 必须传入一个 unique_lock,并可选地传入一个谓词(lambda 或函数对象)。推荐始终使用带谓词的版本,避免虚假唤醒导致的问题。
两种写法对比:
- 不推荐:
cv.wait(lock);
if (!data_queue.empty()) { ... } - 推荐:
cv.wait(lock, []{ return !data_queue.empty(); });
带谓词的 wait 会自动循环检查条件,直到为真才返回,更安全简洁。
notify_one vs notify_all
- notify_one:唤醒一个等待的线程,适用于只有一个线程需要被通知的情况(如单个消费者)
- notify_all:唤醒所有等待线程,适用于广播场景,例如多个消费者都在等任务
注意:notify 不保证立即切换到目标线程,只是使其进入就绪状态。
基本上就这些。掌握 condition_variable 的核心在于理解“等待某个条件 + 锁保护共享状态 + 正确通知”的模式。实际使用中要特别注意锁的粒度和 notify 的时机,避免死锁或遗漏唤醒。以上就是C++如何使用std::condition_variable_C++多线程同步与条件变量使用的详细内容,更多请关注其它相关文章!
# 尼克
# 西安seo真实收入
# 关键词替换seo
# 防城港律师网站推广
# 襄阳网站推广怎么样
# 乐清网站建设北路小学
# 贸易建设网站
# 教育网站推广哪家信誉好
# 巴中搜狗问答推广营销
# 酒泉网站建设排名优化
# seo辅助软件是干嘛的
# 都在
# 有什么区别
# 工具
# 死锁
# 适用于
# 多个
# 是一个
# 如何实现
# 多线程
# 如何使用
# stream
# ios
# c++
# ai
相关栏目:
【
科技资讯46185 】
【
网络学院92790 】
相关推荐:
小猿搜题在线学习页面在哪_小猿搜题在线学习中心入口
邮政快递包裹最新位置 邮政快递实时追踪入口
C++指针和引用有什么区别_C++内存管理核心概念深度解析
sublime如何处理大型CSV文件的列对齐_sublime高级表格编辑插件指南
利用5118提升短视频内容效果_5118短视频关键词优化方法
CSS自定义字体样式被系统字体替换怎么办_font-face方式指定font-display控制渲染策略
一加手机电池耗电快怎么办_一加手机电池耗电快的解决方法
谷歌邮箱注册显示错误Gmail服务器异常与延迟处理
支付宝如何管理隐私设置_支付宝隐私保护的配置技巧
漫蛙2(台版)官方入口地址 漫蛙2(台版)正版漫画网页端
CSS如何设置hover状态颜色_hover伪类调整背景或文字颜色
Word2013如何插入视频和音频媒体_Word2013媒体插入的多媒体支持
J*a应用集成GitHub CLI与API认证指南
优化MinIO list_objects_v2 操作的性能瓶颈与最佳实践
Tabulator表格中精确实现日期时间排序的指南
铁路12306的积分有效期是多久_铁路12306积分有效期说明
漫蛙2漫画入口 漫蛙正版网页漫画直达网址
百度网盘网页版入口 百度网盘网页版官方登录网址
Mudbox图层蒙版怎么用_Mudbox图层蒙版数字雕刻应用技巧
高德地图公交到站提醒失败如何解决 高德提醒权限设置
创客贴用户入口官网登录 创客贴网页版电脑版系统
J*aScript中高效清空DOM列表元素:解决for循环中断与任务管理问题
免费抖音短视频入口_抖音网页版短视频免费通道
win11专注助手在哪 Win11免打扰模式设置与自动化规则【指南】
浏览器打开即用 美图秀秀网页版入口
J*aScript中针对特定容器内图片动画的实现教程
Golang并发任务中错误如何聚合_Golang goroutine error收集方式
J*aScript数据结构转换:将对象数组按类别分组
Win11如何开启讲述人功能 Win11屏幕阅读器(讲述人)开启与关闭【教程】
Win10自动更新怎么关闭 Win10永久关闭系统更新的两种方法【终极版】
Linux如何构建多环境配置管理_Linux多环境配置方案
Pandas DataFrame 高效批量赋值:告别循环与笛卡尔积误区
痛风发作了怎么办? 快速止痛和后期饮食调理
《主播少女的秘密账号迷宫》首支宣传片
深入理解Go语言中的指针类型:以*string为例
谷歌浏览器浏览体验优化_谷歌浏览器新版直连永久可用提示
快手赚钱渠道_快手收益来源
谷歌浏览器如何快速清除某个网站的数据_Chrome网站缓存清理方法
Odoo 16:在表单视图中基于当前记录动态修改Tree视图属性
Win11怎么开启省电模式_Win11电池节电模式自动开启
树莓派传感器触发:通过Twilio API发送WhatsApp消息教程
css绝对定位元素脱离父容器怎么办_确保父元素position非static
Win11怎么查看电脑配置_Win11硬件配置检测工具使用
Python实时数据流中的动态最值查找策略
J*a应用程序首次运行自动创建文件与目录的最佳实践
响应式容器内容自动缩放与宽高比维持教程
理解Python模块与全局变量的作用域管理
抓大鹅解压小游戏 抓大鹅摸鱼解压入口
谷歌浏览器一键优化方案_谷歌浏览器直达主页极速不卡版
steam官方入口大全 steam账号注册及操作指南


2025-11-16
浏览次数:次
返回列表
return !data_queue.empty() || finished;
});
if (!data_queue.empty()) {
int value = data_queue.front();
data_queue.pop();
std::cout << "消费: " << value << "\n";
}
if (data_queue.empty() && finished) {
break; // 结束循环
}
lock.unlock();
}
}