信息发布→ 登录 注册 退出

c++ 怎么使用条件变量std::condition_variable_c++线程等待与条件同步实现

发布时间:2025-11-15

点击量:
std::condition_variable用于线程同步,需与std::mutex配合使用,通过wait()等待条件,notify_one()/notify_all()通知;必须在锁保护下等待,推荐带谓词的wait防止虚假唤醒,通知前应先修改共享数据并释放锁。

c++ 怎么使用条件变量std::condition_variable_c++线程等待与条件同步实现

在C++多线程编程中,std::condition_variable 是实现线程间条件同步的重要工具。它通常与 std::mutex 配合使用,用于让一个或多个线程等待某个特定条件成立后再继续执行。

条件变量的基本原理

条件变量本身不存储状态,它只是一个通知机制。线程可以:

  • 等待某个条件成立(调用 wait())
  • 当条件可能变化时,由其他线程发出通知(notify_one() 或 notify_all())

关键点是:等待必须在互斥锁保护下进行,且通常使用循环检查条件,防止虚假唤醒。

基本使用步骤

以下是使用 std::condition_variable 的标准模式:

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

std::mutex mtx;
std::condition_variable cv;
bool ready = false;

void worker_thread() {
    std::unique_lock<std::mutex> lock(mtx);
    // 等待直到 ready 为 true
    cv.wait(lock, []{ return ready; });
    std::cout << "工作线程开始执行任务\n";
}

int main() {
    std::thread worker(worker_thread);

    std::this_thread::sleep_for(std::chrono::seconds(1));
    
    {
        std::lock_guard<std::mutex> lock(mtx);
        ready = true;
    }
    cv.notify_one();  // 唤醒一个等待的线程

    worker.join();
    return 0;
}

wait 的两种形式

cv.wait(lock):无条件等待,醒来后需手动检查条件。

Reachout.ai Reachout.ai

一个AI驱动的视频开发平台,专为忙碌的企业家和销售团队打造

Reachout.ai 142 查看详情 Reachout.ai

cv.wait(lock, predicate):带条件的等待,等价于:

while (!predicate()) {
    wait(lock);
}

推荐使用带谓词的版本,能自动处理虚假唤醒。

通知方式的选择

  • notify_one():唤醒一个等待线程,适用于只有一个消费者的情况
  • notify_all():唤醒所有等待线程,适用于多个消费者或广播场景

注意:通知前应先修改共享数据并释放锁,否则被唤醒的线程可能无法立即获取锁。

生产者-消费者模型示例

常见应用场景:用条件变量实现线程安全的任务队列。

#include <queue>
#include <thread>
#include <condition_variable>

std::queue<int> tasks;
std::mutex task_mutex;
std::condition_variable task_cv;
bool finished = false;

void producer() {
    for (int i = 0; i < 5; ++i) {
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
        std::lock_guard<std::mutex> lock(task_mutex);
        tasks.push(i);
        std::cout << "生产任务: " << i << "\n";
        task_cv.notify_one();
    }
    {
        std::lock_guard<std::mutex> lock(task_mutex);
        finished = true;
    }
    task_cv.notify_all();  // 通知消费者结束
}

void consumer() {
    while (true) {
        std::unique_lock<std::mutex> lock(task_mutex);
        task_cv.wait(lock, []{ return !tasks.empty() || finished; });

        if (finished && tasks.empty()) break;

        int task = tasks.front();
        tasks.pop();
        lock.unlock();  // 处理任务时不持有锁
        std::cout << "消费任务: " << task << "\n";
        std::this_thread::sleep_for(std::chrono::milliseconds(50));
    }
}
基本上就这些。核心是:用互斥锁保护共享状态,用条件变量等待特定条件,记得处理虚假唤醒和正确发送通知。

以上就是c++++ 怎么使用条件变量std::condition_variable_c++线程等待与条件同步实现的详细内容,更多请关注其它相关文章!


相关文章: 一加 14R 快充无反应_一加 14R 充电优化  解决macOS上安装pyhdf时‘hdf.h’文件缺失的编译错误  XML中包含HTML标签导致解析错误? 正确嵌入非XML数据的两种方法  在J*a中如何开发简易博客标签推荐系统_博客标签推荐项目实战解析  qq游戏手机版下载安装_qq游戏移动端入口  Composer如何处理Git子模块(submodule)依赖_Composer与Git Submodule的对比与选择  虫虫漫画精品漫画官网_虫虫漫画精品漫画官网进入精品漫画  C++如何检测键盘输入_C++ _kbhit与_getch函数非阻塞输入  利用5118提升短视频内容效果_5118短视频关键词优化方法  WooCommerce产品页高级定制:实现基于分类的交叉销售  小米汽车11月交付量突破40000台!雷军:将继续努力  初次安装JDK时环境变量如何正确配置_J*A_HOME与PATH设置规则讲解  AO3中文官网链接_AO3网页版稳定镜像站  飞书妙记怎样用语音转文字速记_飞书妙记用语音转文字速记【速记方法】  如何仅使用CSS更改登录界面背景图像图标的颜色  响应式图片在网页设计中的正确实现方法  Angular中单选按钮的正确使用与常见陷阱解析  Kafka Streams中基于消息头条件过滤消息的实现指南  抖音极速版最新版本 抖音极速版官方下载地址  文本文档写html代码怎么运行_文本文档html代码运行步骤【教程】  离线运行Go语言之旅:本地部署与GOPATH配置指南  深入理解Go语言中的指针类型:以*string为例  PHP 枚举:根据字符串获取枚举案例的策略与实现  如何优雅地扩展SprykerGlue后端API授权逻辑,使用spryker/glue-backend-api-application-authorization-connector-extension  ACG动漫手机版官网入口 手机ACG动漫APP在线观看正版  单12V-2&#215;6实现为RTX 5090供电750W!甚至都没敢跑分  Golang如何使用new_Go new分配内存机制讲解  在Typer应用中优雅地处理和重组任意命令行参数  如何使用CaptainHook和Composer管理Git钩子_在提交前自动运行代码检查的Composer配置  C++的std::mdspan是什么_C++23中用于操作多维数组的非拥有视图  抖音小游戏合成大西瓜免费秒玩入口链接 抖音小游戏热门合集秒玩网站  Python实时数据流中的动态最值查找策略  J*a最大堆Heapify方法修复:索引计算与边界条件深度解析  知音漫客官网漫画下载_知音漫客网页版阅读记录  没有大陆身份证/银行卡如何实名微信? 亲测有效的几种方法分享  CSS Flexbox如何实现多行排列_flex-wrap wrap自动换行显示  J*aScript中安全有效地处理localStorage字符串数据  Excel组合图表怎么做 Excel创建柱状图与折线组合图教程【图表】  我的世界官方游戏入口 我的世界官网平台直达链接  PHP文件上传至S3:策略、考量与避免本地存储的挑战  优化HTML表单样式:解决输入框焦点跳动与元素间距问题  PHP中获取MongoDB服务器运行时间(Uptime)的专业指南  C++如何连接MySQL数据库_C++使用Connector/C++操作MySQL数据库教程  微博网页版直接访问 微博网页版账号管理快速入口  铁路12306的积分有效期是多久_铁路12306积分有效期说明  Sublime Text怎么显示空格和制表符_Sublime显示不可见字符设置  漫蛙漫画官方首页 漫蛙2漫画在线阅读入口  Promise错误处理:在catch后终止链式then执行的策略  Bilibili动漫最新防封地址发布-Bilibili动漫2025年最稳正版入口推荐  Selenium Python中处理点击后新窗口加载冻结问题的策略与实践 

在线客服
服务热线

服务热线

4008988990

微信咨询
二维码
返回顶部
×二维码

截屏,微信识别二维码

打开微信

微信号已复制,请打开微信添加咨询详情!