C++ 标准库 condition_variable 功能 用法运用 详解

news/2025/3/10 11:01:35/文章来源:https://www.cnblogs.com/baisemoshui/p/18762162

C++标准库中的<condition_variable>头文件为多线程编程提供了一种高效的线程同步机制。以下是对<condition_variable>的功能、用法及运用的详细解析:

一、功能

<condition_variable>提供了条件变量(condition variable)的类和函数,用于实现线程间的等待/通知机制。条件变量允许一个或多个线程等待某个条件变为真(即被满足),并通过另一个线程的通知来唤醒这些等待的线程。这种机制在多线程编程中非常有用,特别是在生产者-消费者模型、线程池等场景中。

二、主要类及功能

  1. std::condition_variable

    • 用于普通线程同步。
    • 提供了waitnotify_onenotify_all等成员函数。
    • wait函数会阻塞当前线程,直到条件变量被通知。它通常与std::unique_lock<std::mutex>一起使用,以确保在等待条件变量时释放互斥锁,防止死锁。
    • notify_one函数会唤醒一个等待此条件变量的线程。
    • notify_all函数会唤醒所有等待此条件变量的线程。
  2. std::condition_variable_any

    • std::condition_variable的通用版本,支持与任意的锁类型配合使用。
    • 提供了与std::condition_variable相同的成员函数,但更加灵活。

三、用法

  1. 创建条件变量

    std::condition_variable cv;
    
  2. 使用条件变量进行等待

    std::unique_lock<std::mutex> lock(mutex); // 先获取互斥锁
    cv.wait(lock); // 等待条件满足,期间会自动释放锁并阻塞当前线程
    

    或者,使用带有谓词的等待:

    cv.wait(lock, []{ return some_condition; }); // 当some_condition为true时,继续执行
    
  3. 通知条件满足

    cv.notify_one(); // 通知一个等待的线程条件满足
    cv.notify_all(); // 通知所有等待的线程条件满足
    
  4. 使用条件变量进行超时等待

    cv.wait_for(lock, std::chrono::seconds(5)); // 最多等待5秒钟
    

    或者,使用带有谓词的超时等待:

    bool result = cv.wait_for(lock, std::chrono::seconds(5), []{ return some_condition; });
    

四、运用示例

以下是一个简单的生产者-消费者模型示例,展示了如何使用<condition_variable>进行线程同步:

#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <queue>std::queue<int> buffer;
const unsigned int MAX_BUFFER_SIZE = 10;
std::mutex mtx;
std::condition_variable cv;void producer(int id) {for (int i = 0; i < 20; ++i) {std::unique_lock<std::mutex> lock(mtx);cv.wait(lock, [] { return buffer.size() < MAX_BUFFER_SIZE; });buffer.push(i);std::cout << "Producer " << id << " produced: " << i << std::endl;lock.unlock(); // 注意:这里实际上不需要显式解锁,因为cv.wait在条件满足或超时后会重新锁定互斥锁cv.notify_all();}
}void consumer(int id) {for (int i = 0; i < 20; ++i) {std::unique_lock<std::mutex> lock(mtx);cv.wait(lock, [] { return !buffer.empty(); });int item = buffer.front();buffer.pop();std::cout << "Consumer " << id << " consumed: " << item << std::endl;lock.unlock(); // 同样,这里不需要显式解锁cv.notify_all();}
}int main() {std::thread prod1(producer, 1);std::thread prod2(producer, 2);std::thread cons1(consumer, 1);std::thread cons2(consumer, 2);prod1.join();prod2.join();cons1.join();cons2.join();return 0;
}

在这个示例中,生产者线程会等待缓冲区中有足够空间后再生产新数据,而消费者线程会等待缓冲区非空后从中取出数据。条件变量cv用于在生产者和消费者之间传递信号,以实现线程同步。

五、注意事项

  1. 避免虚假唤醒:条件变量的wait函数可能会因虚假唤醒(spurious wakeup)而提前返回。因此,建议将wait的调用写成带有谓词的形式,以确保线程只有在条件成立时才会继续执行。
  2. 最小化锁的持有时间:为了提高性能并减少锁竞争,应尽量缩短锁的持有时间。可以在获取锁后尽快进行必要的操作,然后释放锁并通知等待的线程。
  3. 避免死锁:在使用条件变量时,要确保在等待条件变量时始终释放互斥锁。此外,还要严格按照加锁顺序来获取锁,以避免循环依赖导致的死锁。

综上所述,<condition_variable>为C++多线程编程提供了一种高效的线程同步机制。通过合理使用条件变量和互斥锁,可以实现线程间的等待/通知机制,从而确保数据的一致性和线程安全。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/896725.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ERP如何高效管理委外加工?全流程拆解!

很多工厂都有委外加工的需求,比如某些零部件自己做成本太高、工艺太复杂,干脆交给外面的供应商去做。 问题来了,委外加工一旦管理不好,就会面临很多坑:订单交付时间不稳定,供应商老是拖 质量难以保证,返工率高 成本难控制,感觉钱花出去了但效果一般 物料进出混乱,不知…

一文全知晓,电脑上的hyper有何作用

随着虚拟现实房产展示的兴起,为购房者提供沉浸式的看房体验成为房产销售的新趋势。虚拟机技术在虚拟现实房产展示中,为房产展示软件提供稳定运行环境,实现房屋内部结构和装修的逼真呈现,让购房者足不出户即可看房。今天给大家介绍电脑上的hyper有何作用?电脑上的hyper有何…

【VMware vSphere】VMware 环境本地部署运行 DeepSeek-R1 大模型(纯 CPU)。

DeepSeek 是由中国杭州深度求索公司开发的智能 AI 助手,一个基于人工智能技术构建的虚拟助手,旨在通过自然语言处理和机器学习算法来理解并回应用户的问题与请求。它可以提供多种服务,包括但不限于信息检索、数据分析、语言翻译、知识问答以及日常生活的辅助建议等。 其实,…

Contest3897 - 计科23级算法设计与分析上机作业-01

题目链接 A.判断一个数能否被3,5,7整除 题面思路 直接模拟即可 示例代码 #include<bits/stdc++.h>using namespace std;#define ll long long //#define int ll #define pii pair<int, int> #define all(x) x.begin(),x.end() #define fer(i, m, n) for(int i = m;…

Ollama+DeepSeek+SlackBot

本文介绍了一种使用Slack聊天工具中的机器人SlackBot的API接口,实现本地化部署Ollama的DeepSeek大模型的远程通讯方案。相比于调用公网的API接口,数据隐私稍微好一点点。最终的方案应该是自建加密聊天工具+Ollama本地化部署,但是这个时间成本有点高,用户可以自行尝试。技术…

GreatSQL 8.0.32-27 GA (2025-3-10)

GreatSQL 8.0.32-27 GA (2025-3-10)版本信息发布时间:2025年3月10日版本号:8.0.32-27, Revision aa66a385910下载链接:https://gitee.com/GreatSQL/GreatSQL/releases/tag/GreatSQL-8.0.32-27用户手册:https://greatsql.cn/docs/8.0.32-27/改进提升 在GreatSQL 8.0.32-27版…

牛客题解 | 求整数的阶乘

牛客题库题解题目 题目链接 题解: 题目难度:中等难度 难点: 1.由于数据太大无法通过整数类型表示,因此用字符串存储结果 2.对于每个字符串从尾部开始进行简单的乘法,在其中考虑进位 知识点:大数相乘 思路: 1.构造multiply(int x, int res[], int res_size)函数,数组res…

OP13常见问题

1.直振与切料口的对中 问题:对中不良,导致送料不到位,对光传感器检测不到产品,报警直振缺料。解决方法: 先检查气缸自带的行程调节器有无松动,如果没有松动,通过微调振动盘机构的位置及底脚高度,实现切料口上下左右的对中。2.机器人夹爪气缸磁开线路 1.M8接头长期晃动,…

Android Studio 2022下载与安装

1、安装包 扫描下方二维码关注「软知社」,后台回复【066】三位数字即可免费获取分享链接,无广告拒绝套路; 2、安装教程解压下载安装包,双击Setup.exe安装,弹窗安装对话框点击下一步默认,点击下一步选择安装目录,建议选择C盘之外,点击下一步点击安装安装完成,点击下一…

Adobe Photoshop 2025下载与安装

‌Photoshop 2025的安装环境要求主要包括操作系统、处理器、内存、显卡、显示器分辨率和硬盘空间等方面的具体要求。‌ 操作系统要求‌Windows‌:支持Windows 10(版本21H2)或更高版本,不支持Windows的长期服务版(LTSC)。处理器要求‌Windows‌:支持64位的多核Intel或AMD…

Capture one 2023下载与安装教程

1、安装包 扫描下方二维码关注「软知社」,后台回复【061】三位数字即可免费获取分享链接,无广告拒绝套路; 2、安装教程(建议关闭杀毒软件和系统防护)解压下载安装包,双击软件安装,弹窗安装对话框选择中文,点击确定选择‘我同意。’ 点击下一步选择安装目录,建议C盘之外…

S3FT选择性自监督微调:通过智能选择训练样本提升大模型整体表现

选择性自我监督微调(Selective Self-to-Supervised Fine-Tuning,S3FT)是一种创新的大语言模型微调方法,该方法通过部署专门的语义等价性判断器来识别训练集中模型自身生成的正确响应。在微调过程中,S3FT策略性地结合这些正确响应与剩余样本的标准答案(或其释义版本)来优…