新闻中心

C++如何使用std::condition_variable_C++多线程同步与条件变量使用

2025-11-16
浏览次数:
返回列表
std::condition_variable用于线程同步,配合std::mutex实现等待-通知机制,如生产者-消费者模型中,通过wait()阻塞线程直到条件满足,notify_one()或notify_all()唤醒线程,需用unique_lock并结合谓词防止虚假唤醒,确保正确处理共享状态。

c++如何使用std::condition_variable_c++多线程同步与条件变量使用

在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

Whimsical推出的AI思维导图工具

Whimsical 182 查看详情 Whimsical
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账号注册及操作指南 

搜索