欢迎来到徐庆高(Tea)的个人博客网站
磨难很爱我,一度将我连根拔起。从惊慌失措到心力交瘁,我孤身一人,但并不孤独无依。依赖那些依赖我的人,信任那些信任我的人,帮助那些给予我帮助的人。如果我愿意,可以分裂成无数面镜子,让他们看见我,就像看见自己。察言观色和模仿学习是我的领域。像每个深受创伤的人那样,最终,我学会了随遇而安。
当前位置: 日志文章 > 详细内容

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

2025年07月10日 C/C++
作用:std::condition_variable是 c++ 多线程编程中用于线程间同步的核心工具,其使用场景和核心价值体现在以下几个方面: 一、何时使用std::condition_varia

作用: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 条件变量内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!