0

0

c++怎么使用条件变量std::condition_variable_c++线程通信与等待机制

裘德小鎮的故事

裘德小鎮的故事

发布时间:2025-11-10 20:05:14

|

681人浏览过

|

来源于php中文网

原创

std::condition_variable用于线程同步,配合mutex和共享变量实现高效等待与通知机制,如生产者-消费者模型中通过wait()和notify_one()协调线程,避免轮询并处理虚假唤醒。

c++怎么使用条件变量std::condition_variable_c++线程通信与等待机制

在C++多线程编程中,std::condition_variable 是一种重要的同步机制,用于线程间的通信与等待。它通常配合 std::unique_lock<:mutex> 使用,实现一个线程等待某个条件成立,而另一个线程在条件达成时通知等待中的线程继续执行。

基本概念:条件变量的作用

条件变量允许线程**主动挂起**,直到接收到“条件已满足”的信号。这种机制避免了轮询检查共享状态,提高了效率和响应性。

典型使用场景包括:

  • 生产者-消费者模型
  • 任务队列的空/满状态控制
  • 等待某个资源初始化完成

关键组件与用法步骤

使用 std::condition_variable 需要三个核心部分:

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

微信 WeLM
微信 WeLM

WeLM不是一个直接的对话机器人,而是一个补全用户输入信息的生成模型。

下载
  • std::condition_variable 实例:用于阻塞和唤醒线程
  • std::mutexstd::unique_lock:保护共享数据并配合条件变量使用
  • 一个表示条件的共享变量(如布尔值、队列是否为空等)

标准使用流程如下:

  1. 等待线程获取互斥锁,然后调用 wait() 方法,并传入锁和一个判断条件的谓词
  2. 条件变量会自动释放锁,使其他线程可以修改共享状态
  3. 当其他线程修改状态后,调用 notify_one()notify_all() 唤醒等待线程
  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::unique_lock lock(mtx);
        data_queue.push(i);
        std::cout << "生产: " << i << "\n";
        lock.unlock();
        cv.notify_one(); // 通知消费者
    }
    {
        std::unique_lock lock(mtx);
        finished = true;
    }
    cv.notify_one(); // 通知消费者生产结束
}

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();
            std::cout << "消费: " << value << "\n";
        }

        if (data_queue.empty() && finished) {
            break; // 结束循环
        }
        lock.unlock();
    }
    std::cout << "消费者退出\n";
}

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

    p.join();
    c.join();

    return 0;
}

说明:

  • 消费者调用 cv.wait() 时传入了一个 lambda 表达式作为条件判断,这是推荐写法,可防止虚假唤醒
  • 每次生产后调用 notify_one(),唤醒一个等待线程
  • 使用 unique_lock 是因为 wait() 内部需要解锁和重新加锁

注意事项与最佳实践

使用条件变量时需注意以下几点:

  • 永远在循环中检查条件,不要只依赖一次判断(防止虚假唤醒)
  • 确保共享数据始终被互斥锁保护
  • 调用 notify_* 并不会立即切换线程,只是解除阻塞状态
  • 如果多个线程等待,使用 notify_all() 可唤醒全部,但可能造成“惊群效应”
基本上就这些。掌握好 condition_variable 的使用模式,能有效解决线程间协调问题。

相关专题

更多
lambda表达式
lambda表达式

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

202

2023.09.15

python lambda函数
python lambda函数

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

187

2025.11.08

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

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

467

2023.08.10

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

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

83

2025.12.24

excel制作动态图表教程
excel制作动态图表教程

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

24

2025.12.29

freeok看剧入口合集
freeok看剧入口合集

本专题整合了freeok看剧入口网址,阅读下面的文章了解更多网址。

74

2025.12.29

俄罗斯搜索引擎Yandex最新官方入口网址
俄罗斯搜索引擎Yandex最新官方入口网址

Yandex官方入口网址是https://yandex.com;用户可通过网页端直连或移动端浏览器直接访问,无需登录即可使用搜索、图片、新闻、地图等全部基础功能,并支持多语种检索与静态资源精准筛选。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

207

2025.12.29

python中def的用法大全
python中def的用法大全

def关键字用于在Python中定义函数。其基本语法包括函数名、参数列表、文档字符串和返回值。使用def可以定义无参数、单参数、多参数、默认参数和可变参数的函数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

16

2025.12.29

python改成中文版教程大全
python改成中文版教程大全

Python界面可通过以下方法改为中文版:修改系统语言环境:更改系统语言为“中文(简体)”。使用 IDE 修改:在 PyCharm 等 IDE 中更改语言设置为“中文”。使用 IDLE 修改:在 IDLE 中修改语言为“Chinese”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

18

2025.12.29

热门下载

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

精品课程

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

共21课时 | 2.3万人学习

【web前端】Node.js快速入门
【web前端】Node.js快速入门

共16课时 | 1.9万人学习

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

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