当前位置: 首页 > news >正文

C++(14): STL条件变量std::condition_variable

1. 简述

        在C++的标准模板库(STL)中,std::condition_variable是一个非常重要的同步原语,用于在多线程编程中实现线程间的条件同步。它允许一个或多个线程等待某个条件成立,当条件成立时,等待的线程会被唤醒并继续执行。

2. 基本概念

        std::condition_variable通常与std::mutex一起使用,用于保护共享数据并同步线程。在多线程环境中,多个线程可能同时访问和修改共享数据,这可能导致数据不一致或其他不可预测的行为。std::mutex用于确保在任何时候只有一个线程可以访问共享数据,而std::condition_variable则用于在特定条件下唤醒等待的线程。

3. 条件变量的工作原理

        条件变量允许线程在某些条件不满足时挂起(等待),并在条件变为真时被唤醒。这通常涉及到以下三个步骤:

等待条件

线程在进入临界区后,检查条件是否满足。如果不满足,线程会释放互斥锁并进入等待状态。

通知其他线程

        当条件可能已经变为真的事件发生时,另一个线程会通知等待的线程。

重新检查条件

        被通知的线程重新获取互斥锁,并重新检查条件。如果条件仍然不满足,线程可能会再次等待。

4. 主要函数

        std::condition_variable提供了几个主要的成员函数,用于实现线程间的条件同步:

wait(std::unique_lock<std::mutex>& lock)

        使当前线程进入等待状态,直到另一个线程调用notify_one()或notify_all()。在等待期间,lock参数指定的互斥锁会被自动释放,允许其他线程访问共享数据。当线程被唤醒时,互斥锁会再次被锁定。

wait_for(std::unique_lock<std::mutex>& lock, std::chrono::duration<Rep, Period> rel_time)

        与wait()类似,但允许指定一个超时时间。如果超时时间到达而条件仍未成立,线程将停止等待并继续执行。

wait_until(std::unique_lock<std::mutex>& lock, std::chrono::time_point<Clock, Duration> abs_time)

        与wait_for()类似,但允许指定一个绝对时间作为超时时间。

notify_one()

        唤醒等待在condition_variable上的一个线程(如果有的话)。

notify_all()

        唤醒等待在condition_variable上的所有线程。

        std::condition_variable 的 wait、notify_one 和 notify_all 函数都要求在调用时拥有互斥锁的所有权。std::unique_lock 通过提供对互斥锁的独占控制,确保了这些条件变量函数能够安全地与锁的获取和释放配合工作。

使用 std::unique_lock 包装 std::mutex 是为了确保线程安全、简化资源管理、防止死锁,并与条件变量正确配合。

5. 例程

        在这个程序里,我们的条件就是ready变量变为true,然后再执行其他操作。

#include <iostream>  #include <thread>  #include <mutex>  #include <condition_variable>  std::mutex mtx;  std::condition_variable cv;  bool ready = false;  void print_id(int id) {  std::unique_lock<std::mutex> lck(mtx);  /** 如果条件不满足,则等待. */while (!ready) {cv.wait(lck); ///< 等待、阻塞}/** 执行其他操作. */}  void Signal() {  std::unique_lock<std::mutex> lck(mtx);  ready = true;  ///< 设置条件为true  cv.notify_all();  ///< 唤醒所有等待的线程  }  int main(int argc, char* argv[]){std::thread threads[10];  /** 发起10个线程. */  for (int i = 0; i < 10; ++i)  threads[i] = std::thread(print_id, i);  std::cout << "10 threads ready to race...\n";  Signal(); ///< 唤醒线程,继续执行.for (auto& th : threads){th.join();}return 0;  }

相关文章:

C++(14): STL条件变量std::condition_variable

1. 简述 在C的标准模板库&#xff08;STL&#xff09;中&#xff0c;std::condition_variable是一个非常重要的同步原语&#xff0c;用于在多线程编程中实现线程间的条件同步。它允许一个或多个线程等待某个条件成立&#xff0c;当条件成立时&#xff0c;等待的线程会被唤醒并继…...

Harmony与Android项目结构对比

主要文件对应 Android文件HarmonyOS文件清单文件AndroidManifest.xmlmodule.json5Activity/Fragmententryability下的ts文件XML布局pages下的ets文件resresourcesModule下的build.gradleModule下的build-profile.json5gradlehvigor根目录下的build.gradle根目录下的build-profi…...

langchain 学习笔记-FunctionCalling三种方式

ChatGPT 基于海量的训练数据生成答案&#xff0c;所以它无法回答训练数据中没有的信息或搜索信息 。人们希望 ChatGPT 具有对话以外的各种功能&#xff0c;例如“我想管理我的待办事项列表”。 函数调用是对此类请求的响应。 通过使用函数调用&#xff0c;ChatGPT 现在可以在生…...

CNAS软件测试公司有什么好处?如何选择靠谱的软件测试公司?

CNAS认可是中国合格评定国家认可委员会的英文缩写&#xff0c;由国家认证认可监督管理委员会批准设立并授权的国家认可机构&#xff0c;统一负责对认证机构、实验室和检验机构等相关机构的认可工作。 在软件测试行业&#xff0c;CNAS认可具有重要意义。它标志着一个软件测试公…...

Cohere推出全新升级版RAG大型AI模型:支持中文,搭载1040亿参数,现开源其权重!

4月5日&#xff0c;知名类ChatGPT平台Cohere在其官方网站上发布了一款全新的模型——Command R。 据官方消息&#xff0c;Command R拥有1040亿个参数&#xff0c;并且支持包括英语、中文、法语、德语在内的10种语言。这一模型的显著特点之一在于其对内置的RAG&#xff08;检索增…...

搭建前后端的链接(java)

搭建前后端的链接(java) 一.前提 1.1 javaEE 搭建前后端的链接首先需要用到javaEE&#xff0c;也就是java企业版&#xff0c;也就是java后端(后端javaSE) 利用javaEE和前端交互&#xff0c;javaSE和数据库交互&#xff0c;javaSE和javaEE之间再进行交互就实现了前后端的交互…...

Java多路查找树(含面试大厂题和源码)

多路查找树&#xff08;Multiway Search Tree&#xff09;&#xff0c;也称为B树或B树&#xff0c;是一种自平衡的树形数据结构&#xff0c;用于存储大量数据&#xff0c;通常用于数据库和文件系统中。它允许在查找、插入和删除操作中保持数据的有序性&#xff0c;同时优化了磁…...

day6 | 哈希表 part-2 | 454 四数相加II 、383. 赎金信、15. 三数之和、18. 四数之和

今日任务 454 四数相加II (题目: . - 力扣&#xff08;LeetCode&#xff09;)383 赎金信 &#xff08;题目: . - 力扣&#xff08;LeetCode&#xff09;&#xff09; 454 四数相加II 题目&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 给你四个整数数组 nums1、num…...

Redis常见数据类型(2)

目录 String字符串 常见命令 SET GET MGET MSET SETNX 计数命令 INCR INCRBY DECR DECRBY INCRFLOAT 其它命令 APPEND GETRANGE SETRANGE STRLEN String字符串 字符串是Redis最基础的数据类型, 关于字符串需要特别注意: (1)首先Redis中所有的键的类型都是字符…...

SparkBug解决:Type mismatch; found : org.apache.spark.sql.Column required: Double

def assginFlag(aizmuth:Double):Option[Int] {val interval 0.5val index (aizmuth / interval ).toIntif (index > 0 && index < 720 ) Some(index 1) else None} assginFlag方法中的条件判断条件 (index > 0 && index < 720) 返回的是一个布…...

MQ之————如何保证消息的可靠性

MQ之保证消息的可靠性 1.消费端消息可靠性保证&#xff1a; 1.1 消息确认&#xff08;Acknowledgements&#xff09;&#xff1a; 消费者在接收到消息后&#xff0c;默认情况下RabbitMQ会自动确认消息&#xff08;autoAcktrue&#xff09;。为保证消息可靠性&#xff0c;可以…...

TrollInstallerX官方一键安装巨魔商店

TrollInstallerX是巨魔官方开发的一款一键巨魔商店安装器&#xff0c;完美支持iOS 14.0 – 16.6.1的设备&#xff0c;操作非常简单&#xff0c;TrollInstallerX依然有个小小的限制&#xff0c;部分机型&#xff0c;还是要采用间接安装方法。 一&#xff0c;直接安装方法 通过…...

生成随机图片验证码

随着互联网的不断发展&#xff0c;安全性问题日益突出。为了保障用户账号的安全性&#xff0c;很多网站都引入了验证码机制。验证码是一种区分用户是计算机还是人的公共全自动程序&#xff0c;可以有效防止恶意攻击和自动化脚本的滥用。本文将介绍如何使用Python生成随机图片验…...

【0280】《数据库系统概论》阅读总结(附xmind思维导图)

0. 阅读进展 选择性地读取了《数据库系统概论》一书中的第13、14章节&#xff0c;并对这两章节中较为重点的内容作了总结和归纳&#xff1b;然后以xmind导图形式给出。 1. xmind思维导图 Xmind附件&#xff1a;...

数据结构(二)----线性表(顺序表,链表)

目录 1.线性表的概念 2.线性表的基本操作 3.存储线性表的方式 &#xff08;1&#xff09;顺序表 •顺序表的概念 •顺序表的实现 静态分配&#xff1a; 动态分配&#xff1a; 顺序表的插入&#xff1a; 顺序表的删除&#xff1a; 顺序表的按位查找&#xff1a; 顺序…...

为什么你选择成为一名程序员?

文章目录 ✍选择成为程序员&#xff1a;兴趣与职业发展的交汇&#x1f48e;1 兴趣的驱动&#x1f48e;2 职业发展的需求&#x1f48e;3 结语 ✍选择成为程序员&#xff1a;兴趣与职业发展的交汇 在当今数字化时代&#xff0c;程序员已经成为一个备受瞩目的职业。无论是因为对技…...

【Android】系统启动流程分析 —— SystemServer 处理过程

本文基于 Android 14.0.0_r2 的系统启动流程分析。 SystemServer 进程主要用于创建系统服务&#xff0c;我们熟知的 AMS、WMS 和 PMS 都是由它来创建的&#xff0c;因此掌握 SystemServer 进程是如何启动的&#xff0c;它在启动时做了哪些工作是十分必要的。 一、源码解析 Zyg…...

Web前端—属性描述符

属性描述符 假设有一个对象obj var obj {a:1 }观察这个对象&#xff0c;我们如何来描述属性a&#xff1a; 值为1可以重写可以遍历 我们可以通过Object.getOwnPropertyDescriptor得到它的属性描述符 var desc Object.getOwnPropertyDescriptor(obj, a); console.log(desc);我…...

SpringBoot及其特性

0.前言 Spring 框架提供了很多现成的功能。那么什么是 Spring Boot&#xff1f;使用 Spring 框架&#xff0c;我们可以避免编写基础框架并快速开发应用程序。为了让 Spring 框架提供基础框架&#xff0c;我们需要向 Spring 框架描述有关我们的应用程序及其组件的信息。 不只是…...

「JavaEE」初识进程

初识进程 &#x1f349;进程&#x1f34c;操作系统的进程管理 &#x1f349;PCB 重要属性&#x1f34c;进程的身份标识&#x1f34c;内存指针&#x1f34c;文件描述符表&#x1f34c;进程的状态&#x1f34c;优先级&#x1f34c;记账信息&#x1f34c;上下文 &#x1f349;内存…...

HTML 语义化

目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案&#xff1a; 语义化标签&#xff1a; <header>&#xff1a;页头<nav>&#xff1a;导航<main>&#xff1a;主要内容<article>&#x…...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄

文&#xff5c;魏琳华 编&#xff5c;王一粟 一场大会&#xff0c;聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中&#xff0c;汇集了学界、创业公司和大厂等三方的热门选手&#xff0c;关于多模态的集中讨论达到了前所未有的热度。其中&#xff0c;…...

shell脚本--常见案例

1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件&#xff1a; 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

day52 ResNet18 CBAM

在深度学习的旅程中&#xff0c;我们不断探索如何提升模型的性能。今天&#xff0c;我将分享我在 ResNet18 模型中插入 CBAM&#xff08;Convolutional Block Attention Module&#xff09;模块&#xff0c;并采用分阶段微调策略的实践过程。通过这个过程&#xff0c;我不仅提升…...

基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容

基于 ​UniApp + WebSocket​实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配​微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...

前端开发面试题总结-JavaScript篇(一)

文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包&#xff08;Closure&#xff09;&#xff1f;闭包有什么应用场景和潜在问题&#xff1f;2.解释 JavaScript 的作用域链&#xff08;Scope Chain&#xff09; 二、原型与继承3.原型链是什么&#xff1f;如何实现继承&a…...

【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分

一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计&#xff0c;提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合&#xff1a;各模块职责清晰&#xff0c;便于独立开发…...

如何理解 IP 数据报中的 TTL?

目录 前言理解 前言 面试灵魂一问&#xff1a;说说对 IP 数据报中 TTL 的理解&#xff1f;我们都知道&#xff0c;IP 数据报由首部和数据两部分组成&#xff0c;首部又分为两部分&#xff1a;固定部分和可变部分&#xff0c;共占 20 字节&#xff0c;而即将讨论的 TTL 就位于首…...

C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。

1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj&#xff0c;再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...

听写流程自动化实践,轻量级教育辅助

随着智能教育工具的发展&#xff0c;越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式&#xff0c;也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建&#xff0c;…...