C++中std::condition_variable 条件变量的使用

 更新时间:2025年07月10日 09:39:17   作者:Ring__Rain  
std::condition_variable是C++多线程编程中用于线程间同步的核心工具,适用于需要协调多个线程行为、避免资源浪费的场景,下面就来介绍一下std::condition_variable 条件变量的使用,

作用:std::condition_variable 是 C++ 多线程编程中用于线程间同步的核心工具,其使用场景和核心价值体现在以下几个方面:        

一、何时使用 std::condition_variable?

  • 线程需要等待特定条件成立当某个线程必须等待共享资源的某个状态(如队列非空、任务完成、数据就绪等)时,使用条件变量可以避免忙等待(busy-waiting),从而减少 CPU 资源的浪费。

    经典场景
    • 生产者-消费者模型:消费者线程等待队列中有数据时,生产者线程在添加数据后通过 notify_one() 或 notify_all() 通知消费者。
    • 任务调度:工作线程等待任务队列中出现新任务。
  • 需要多线程协作完成复杂逻辑当多个线程需要按特定顺序协作时(如线程 A 完成预处理后通知线程 B 执行),条件变量提供了一种高效的协调机制。

    示例:主线程等待所有子线程初始化完成后再启动核心逻辑。
  • 避免轮询和资源浪费若用 while (条件不满足) { sleep(); } 实现等待,会导致线程频繁切换上下文和无效轮询,而条件变量通过阻塞线程直接释放 CPU,直到被主动唤醒。

  • 需要动态调整线程行为例如,线程池中的工作线程根据任务负载动态休眠或唤醒。

​二、为什么使用 std::condition_variable?

  • ​解决线程同步中的“等待-通知”问题条件变量通过 wait() 和 notify_*() 的组合,实现线程间的精准通知机制:

    • wait():释放互斥锁并阻塞线程,允许其他线程操作共享资源。
    • ​notify_one()/notify_all():唤醒一个或所有等待线程,确保资源状态变化后及时响应。
  • ​避免虚假唤醒(Spurious Wakeup)​操作系统的底层实现可能导致线程被意外唤醒(即使未收到通知)。条件变量通过 ​谓词(Predicate)​ 参数(如 cv.wait(lock, []{ return ready; }))确保只有在条件真正满足时才继续执行。

  • ​优化锁的粒度条件变量与 std::mutex 配合使用时,允许在等待期间释放锁,其他线程可继续操作共享资源,避免长时间锁竞争。

  • ​替代低效的轮询机制相比轮询(如 sleep() + 循环检查),条件变量通过操作系统级的线程调度实现高效阻塞,减少 CPU 占用。

​三、使用示例与核心步骤

​基本流程

定义共享变量和同步工具

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

等待线程

std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock, [] { return data_ready; });  // 阻塞直到 data_ready 为 true

通知线程

{
    std::lock_guard<std::mutex> lock(mtx);
    data_ready = true;
}
cv.notify_one();  // 唤醒一个等待线程

​经典案例:生产者-消费者模型

#include <queue>
#include <mutex>
#include <condition_variable>

std::mutex mtx;
std::condition_variable cv;
std::queue<int> task_queue;

void producer() {
    for (int i = 0; i < 10; ++i) {
        {
            std::lock_guard<std::mutex> lock(mtx);
            task_queue.push(i);
        }
        cv.notify_one();  // 通知消费者
    }
}

void consumer() {
    while (true) {
        std::unique_lock<std::mutex> lock(mtx);
        cv.wait(lock, [] { return !task_queue.empty(); });  // 等待队列非空
        int task = task_queue.front();
        task_queue.pop();
        lock.unlock();
        // 处理任务
    }
}

​四、注意事项

  • 必须与互斥锁配合使用
    所有对共享变量的修改和访问必须通过互斥锁保护,否则会导致竞态条件(Race Condition)。

  • 正确处理虚假唤醒
    始终使用带谓词的 wait() 形式(如 cv.wait(lock, predicate))。

  • 避免“唤醒丢失”​
    确保在修改共享状态后调用 notify_*(),否则等待线程可能永远阻塞。

​总结

std::condition_variable 的核心价值在于通过 ​等待-通知机制 实现高效的线程同步,适用于需要协调多个线程行为、避免资源浪费的场景。其设计解决了传统轮询的低效问题,并通过与互斥锁的配合优化了多线程程序的性能与安全性。

到此这篇关于C++中std::condition_variable 条件变量的使用的文章就介绍到这了,更多相关C++ std::condition_variable 条件变量内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C++浮点数在内存中的存储详解

    C++浮点数在内存中的存储详解

    大家好,本篇文章主要讲的是C++浮点数在内存中的存储详解,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下
    2022-01-01
  • C语言结构体的全方面解读

    C语言结构体的全方面解读

    C 数组允许定义可存储相同类型数据项的变量,结构是 C 编程中另一种用户自定义的可用的数据类型,它允许你存储不同类型的数据项
    2021-10-10
  • Qt界面美化之自定义qss样式表的详细步骤

    Qt界面美化之自定义qss样式表的详细步骤

    很多人应该和我一样,想做界面才接触的Qt,结果就是做不出来华丽的界面,下面这篇文章主要给大家介绍了关于Qt界面美化之自定义qss样式表的详细步骤,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2023-03-03
  • C语言main函数的参数及其返回值详细解析

    C语言main函数的参数及其返回值详细解析

    main函数的返回值用于说明程序的退出状态。如果返回0,则代表程序正常退出;返回其它数字的含义则由系统决定。通常,返回非零代表程序异常退出
    2013-10-10
  • 使用Matlab制作简易版八分音符酱游戏

    使用Matlab制作简易版八分音符酱游戏

    八分音符酱作为一款声音控制类游戏,当时还是很受大家的喜爱的。本文将用Matlab制作一款简易版的八分音符酱游戏,感兴趣的可以学习一下
    2022-02-02
  • C++避免栈内存溢出的几种实现方法

    C++避免栈内存溢出的几种实现方法

    在C++编程中,一个线程的栈内存通常是有限的,本文就来详细介绍几种避免栈溢出的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-09-09
  • C++实现二叉树的堂兄弟节点查询

    C++实现二叉树的堂兄弟节点查询

    C++实现二叉树的堂兄弟节点查询,是指在二叉树中,找到两个节点深度相同但父节点不同的节点,即为堂兄弟节点。实现这一功能可以通过遍历二叉树并记录节点深度和父节点来实现
    2023-04-04
  • C++ OpenCV实战之手写数字识别

    C++ OpenCV实战之手写数字识别

    这篇文章主要为大家详细介绍了如何使用machine learning机器学习模块进行手写数字识别功能,文中的示例代码讲解详细,感兴趣的可以了解一下
    2022-08-08
  • C语言中scanf函数与空格回车的用法说明

    C语言中scanf函数与空格回车的用法说明

    这篇文章主要介绍了C语言中scanf函数与空格回车的用法说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • C++ 空指针解引用的解决方法

    C++ 空指针解引用的解决方法

    空指针解引用是一种常见且严重的错误,它通常由于指针未初始化、被设置为nullptr或指向无效地址引起,本文主要介绍了C++ 空指针解引用的解决方法,感兴趣的可以了解一下
    2024-08-08

最新评论