0

0

C++如何使用条件变量(condition_variable)_C++ 条件变量使用方法

尼克

尼克

发布时间:2025-10-01 11:09:02

|

591人浏览过

|

来源于php中文网

原创

条件变量需与互斥锁配合使用,通过wait()在循环中检查条件防止虚假唤醒,notify_one()或notify_all()唤醒等待线程,如生产者-消费者模型中保护共享队列并通知状态变化。

c++如何使用条件变量(condition_variable)_c++ 条件变量使用方法

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

1. 条件变量的基本组成

使用 std::condition_variable 需要包含头文件 ,并配合以下组件:

  • std::condition_variable:条件变量对象,用于阻塞和唤醒线程。
  • std::mutexstd::unique_lock<:mutex>:保护共享数据,并在等待时临时释放锁。
  • wait()、notify_one()、notify_all():核心操作函数。

2. 等待条件:wait() 的正确用法

调用 wait() 会阻塞当前线程,直到其他线程通过 notify_one()notify_all() 唤醒它。注意:必须在循环中检查条件,防止虚假唤醒。

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

// 等待线程
std::unique_lock lock(mtx);
cv.wait(lock, []{ return ready; }); // 循环检查 ready 是否为 true

上面的 lambda 表达式是谓词(predicate),wait() 内部会持续检查该条件,只有当条件满足时才真正返回。

立即学习C++免费学习笔记(深入)”;

3. 唤醒线程:notify_one() 与 notify_all()

当某个线程改变了共享状态(如设置 ready = true),应通知等待中的线程:

GentleAI
GentleAI

GentleAI是一个高效的AI工作平台,为普通人提供智能计算、简单易用的界面和专业技术支持。让人工智能服务每一个人。

下载
{
    std::lock_guard lock(mtx);
    ready = true;
}
cv.notify_one();   // 唤醒一个等待线程
// 或 cv.notify_all(); // 唤醒所有等待线程

注意:修改共享数据时需加锁,notify_* 可在解锁后调用,但建议确保数据可见性。

4. 完整示例:生产者-消费者模型

下面是一个典型的使用场景:

#include 
#include 
#include 
#include 
#include 

std::queue data_queue;
std::mutex mtx;
std::condition_variable 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 lock(mtx);
        data_queue.push(i);
        std::cout << "Produced: " << i << "\n";
    }
    {
        std::lock_guard lock(mtx);
        finished = true;
    }
    cv.notify_all(); // 通知所有消费者任务完成
}

void consumer() {
    while (true) {
        std::unique_lock lock(mtx);
        cv.wait(lock, [] { 
            return !data_queue.empty() || finished; 
        });

        if (!data_queue.empty()) {
            int value = data_queue.front();
            data_queue.pop();
            lock.unlock(); // 提前解锁,避免影响其他操作
            std::cout << "Consumed: " << value << "\n";
        }

        if (data_queue.empty() && finished) break;
    }
}

主函数中启动线程即可看到输出:

int main() {
    std::thread p(producer);
    std::thread c1(consumer);
    std::thread c2(consumer);

    p.join();
    c1.join();
    c2.join();
    return 0;
}

基本上就这些。关键是理解:条件变量不保存状态,只负责“通知”,实际条件判断依赖共享变量和谓词检查。用好 wait() + 谓词 + notify 组合,就能安全实现线程同步。

相关专题

更多
lambda表达式
lambda表达式

Lambda表达式是一种匿名函数的简洁表示方式,它可以在需要函数作为参数的地方使用,并提供了一种更简洁、更灵活的编码方式,其语法为“lambda 参数列表: 表达式”,参数列表是函数的参数,可以包含一个或多个参数,用逗号分隔,表达式是函数的执行体,用于定义函数的具体操作。本专题为大家提供lambda表达式相关的文章、下载、课程内容,供大家免费下载体验。

202

2023.09.15

python lambda函数
python lambda函数

本专题整合了python lambda函数用法详解,阅读专题下面的文章了解更多详细内容。

189

2025.11.08

Python lambda详解
Python lambda详解

本专题整合了Python lambda函数相关教程,阅读下面的文章了解更多详细内容。

39

2026.01.05

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

476

2023.08.10

Python 多线程与异步编程实战
Python 多线程与异步编程实战

本专题系统讲解 Python 多线程与异步编程的核心概念与实战技巧,包括 threading 模块基础、线程同步机制、GIL 原理、asyncio 异步任务管理、协程与事件循环、任务调度与异常处理。通过实战示例,帮助学习者掌握 如何构建高性能、多任务并发的 Python 应用。

141

2025.12.24

PPT动态图表制作教程大全
PPT动态图表制作教程大全

本专题整合了PPT动态图表制作相关教程,阅读专题下面的文章了解更多详细内容。

13

2026.01.07

c++ Libcurl用法详解
c++ Libcurl用法详解

本专题整合了c++ Libcurl用法详解,阅读专题下面的文章了解更多详细内容。

0

2026.01.07

c++ Libcurl用法大全
c++ Libcurl用法大全

本专题整合了c++ Libcurl用法详解,阅读专题下面的文章了解更多详细内容。

0

2026.01.07

C++ vector用法汇总
C++ vector用法汇总

本专题整合了C++中vector的用法大全,阅读专题下面的文章了解更多详细内容。

2

2026.01.07

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
React 教程
React 教程

共58课时 | 3.4万人学习

Pandas 教程
Pandas 教程

共15课时 | 0.9万人学习

ASP 教程
ASP 教程

共34课时 | 3.3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号