0

0

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

裘德小鎮的故事

裘德小鎮的故事

发布时间:2025-11-15 09:55:02

|

746人浏览过

|

来源于php中文网

原创

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 的标准模式:

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

#include 
#include 
#include 
#include 

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

void worker_thread() {
    std::unique_lock 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 lock(mtx);
        ready = true;
    }
    cv.notify_one();  // 唤醒一个等待的线程

    worker.join();
    return 0;
}

wait 的两种形式

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

DeepL
DeepL

DeepL是一款强大的在线AI翻译工具,可以翻译31种不同语言的文本,并可以处理PDF、Word、PowerPoint等文档文件

下载

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

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

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

通知方式的选择

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

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

生产者-消费者模型示例

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

#include 
#include 
#include 

std::queue 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 lock(task_mutex);
        tasks.push(i);
        std::cout << "生产任务: " << i << "\n";
        task_cv.notify_one();
    }
    {
        std::lock_guard lock(task_mutex);
        finished = true;
    }
    task_cv.notify_all();  // 通知消费者结束
}

void consumer() {
    while (true) {
        std::unique_lock 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));
    }
}
基本上就这些。核心是:用互斥锁保护共享状态,用条件变量等待特定条件,记得处理虚假唤醒和正确发送通知。

相关专题

更多
线程和进程的区别
线程和进程的区别

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

480

2023.08.10

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

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

143

2025.12.24

Java 桌面应用开发(JavaFX 实战)
Java 桌面应用开发(JavaFX 实战)

本专题系统讲解 Java 在桌面应用开发领域的实战应用,重点围绕 JavaFX 框架,涵盖界面布局、控件使用、事件处理、FXML、样式美化(CSS)、多线程与UI响应优化,以及桌面应用的打包与发布。通过完整示例项目,帮助学习者掌握 使用 Java 构建现代化、跨平台桌面应用程序的核心能力。

34

2026.01.14

php与html混编教程大全
php与html混编教程大全

本专题整合了php和html混编相关教程,阅读专题下面的文章了解更多详细内容。

14

2026.01.13

PHP 高性能
PHP 高性能

本专题整合了PHP高性能相关教程大全,阅读专题下面的文章了解更多详细内容。

33

2026.01.13

MySQL数据库报错常见问题及解决方法大全
MySQL数据库报错常见问题及解决方法大全

本专题整合了MySQL数据库报错常见问题及解决方法,阅读专题下面的文章了解更多详细内容。

18

2026.01.13

PHP 文件上传
PHP 文件上传

本专题整合了PHP实现文件上传相关教程,阅读专题下面的文章了解更多详细内容。

12

2026.01.13

PHP缓存策略教程大全
PHP缓存策略教程大全

本专题整合了PHP缓存相关教程,阅读专题下面的文章了解更多详细内容。

6

2026.01.13

jQuery 正则表达式相关教程
jQuery 正则表达式相关教程

本专题整合了jQuery正则表达式相关教程大全,阅读专题下面的文章了解更多详细内容。

3

2026.01.13

热门下载

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

精品课程

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

共58课时 | 3.6万人学习

Pandas 教程
Pandas 教程

共15课时 | 0.9万人学习

ASP 教程
ASP 教程

共34课时 | 3.6万人学习

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

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