C++ 并发专题 - 条件变量的使用

news2024/11/8 13:34:06

一:概述:

在 C++ 中,条件变量std::condition_variable)是一种用于线程间同步的机制,主要用于在多线程环境中让一个线程等待某个条件满足后再继续执行。条件变量通常配合互斥锁(std::mutex)使用,保证了在访问共享数据时不会发生竞态条件。

二:条件变量的用途:

条件变量用于在某个线程等待另一个线程满足特定条件时进行同步。这通常用于以下几种情况:

  • 生产者-消费者问题:当缓冲区为空时,消费者线程等待生产者线程生产数据;当缓冲区满时,生产者线程等待消费者线程消费数据。
  • 线程池:工作线程等待任务队列中有任务可处理。
  • 任务调度:线程等待其他线程完成某些前置任务。

三:条件变量的工作原理:

  1. 等待条件:线程可以在条件变量上等待,直到某个条件成立(例如,某个标志被设置)。
  2. 通知条件:当某个线程修改共享数据并满足条件时,它可以通过条件变量通知等待的线程,通常使用 notify_one()notify_all() 方法。

四:核心方法:

  • wait:让当前线程等待,直到满足指定条件。在调用 wait 时,条件变量会自动释放与之关联的互斥锁,等待条件满足后再重新获取锁。
  • notify_one:唤醒一个在条件变量上等待的线程。如果没有线程在等待,它什么也不做。
  • notify_all:唤醒所有在条件变量上等待的线程。

五:条件变量的使用注意事项:

  1. 避免虚假唤醒:条件变量的 wait 方法会有可能被虚假唤醒(即条件未改变时线程被唤醒)。因此,通常需要在 wait 语句中使用一个循环来检查条件:
    while (!condition) {
        cv.wait(lock);
    }
    
  2. 锁的管理wait 会释放互斥锁并进入休眠状态,直到被通知并且重新获得锁。使用 std::unique_lock 管理锁是推荐的做法,因为它支持锁的自动管理。
  3. notify_one vs notify_allnotify_one() 只会唤醒一个线程,而 notify_all() 会唤醒所有等待的线程。根据需要选择使用哪一个方法,通常只有一个线程需要继续时使用 notify_one(),而如果有多个线程依赖于同一条件时,则可能需要使用 notify_all()

六:示例

#include <condition_variable>
#include <iostream>
#include <thread>
#include <mutex>

bool dataReady = false; 

std::mutex mutex_;
std::condition_variable condVar1; 
std::condition_variable condVar2; 

int counter = 0;
int COUNTLIMIT = 50; 


void setTrue()
{
	while (counter <= COUNTLIMIT)
	{
		std::unique_lock<std::mutex> lck(mutex_);
		condVar1.wait(lck, [] {return dataReady == false; });
		dataReady = true; 
		++counter;
		std::cout << dataReady << '\n';
		condVar2.notify_one();
	}
}

void setFalse()
{
	while (counter <= COUNTLIMIT)  // 循环直到 counter 达到 COUNTLIMIT
	{
		std::unique_lock<std::mutex> lck(mutex_);  // 获取互斥锁,保护共享数据
		condVar2.wait(lck, [] {return dataReady == true; });  // 等待条件变量,直到 dataReady 为 true
		dataReady = false;  // 修改 dataReady 为 false
		std::cout << dataReady << '\n';  // 输出 dataReady 的值(即 false)
		condVar1.notify_one();  // 唤醒另一个线程,通知它继续执行
	}
}


int main()
{
	std::cout << std::boolalpha << '\n'; 
	std::cout << "Begin: " << dataReady << '\n'; 

	std::thread t1(setTrue);
	std::thread t2(setFalse);

	t1.join();
	t2.join();

	dataReady = false;

	std::cout << "End: " << dataReady << '\n';
	std::cout << '\n';

	return 0; 
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

爬虫-------字体反爬

目录 一、了解什么是字体加密 二. 定位字体位置 三. python处理字体 1. 工具库 2. 字体读取 3. 处理字体 案例1:起点 案例2:字符偏移: 5请求数据 - 发现偏移量 5.4 多套字体替换 套用模板 版本1 版本2 四.项目实战 1. 采集目标 2. 逆向结果 一、了解什么是…

数据分析:宏基因组DESeq2差异分析筛选差异物种

禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍原理:计算步骤:结果:加载R包准备画图主题数据链接导入数据Differential abundance (No BP vs 2BP TA)构建`countData`矩阵过滤低丰度物种构建DESeq数据对象DESeq2差异分析画图Di…

【手撕排序2】快速排序

&#x1f343; 如果觉得本系列文章内容还不错&#xff0c;欢迎订阅&#x1f6a9; &#x1f38a;个人主页:小编的个人主页 &#x1f380; &#x1f389;欢迎大家点赞&#x1f44d;收藏⭐文章 ✌️ &#x1f91e; &#x1f91f; &#x1f918; &#x1f919; &#x1f448; &…

OpenCV自学系列(1)——简介和GUI特征操作

与另一个计算机视觉系列相对应&#xff0c;本系列主要探索OpenCV的具体操作。 学习资源&#xff1a;官网教程 https://docs.opencv.org/4.x/d6/d00/tutorial_py_root.htmlhttps://docs.opencv.org/4.x/d6/d00/tutorial_py_root.html 所有源码均上传至仓库&#xff1a; http…

KION Group EDI 需求分析

梳理EDI需求资料 KION Group将EDI项目中需要的资料公开在其官网上&#xff0c;企业可以点击在 KION Group 官网下载 EDI需求资料 企业可以在以上网址中获取到如下资料&#xff1a; 1.KION Group EDI团队的联系信息以及EDI连接信息 KION Group EDI团队支持7*24小时的支持&am…

OpenDroneMap Webodm

OpenDroneMap & Webodm OpenDroneMap Webodm 开源无人机航拍系列图像及其它系列图像三维重建软件。很棒的开源无人机测绘软件OpenDroneMap,从航拍图像生成精确的地图、高程模型、3D 模型和点云。 应用领域 Mapping & Surveying 测绘和测量 从图像测量获得高精度的可…

计算机网络——网络层导论

转发是局部功能——数据平面 路由是全局的功能——控制平面 网卡 网卡&#xff0c;也称为网络适配器&#xff0c;是计算机硬件中的一种设备&#xff0c;主要负责在计算机和网络之间进行数据传输。 一、主要功能 1、数据传输&#xff1a; 发送数据时&#xff0c;网卡将计算机…

从0开始深度学习(26)——汇聚层/池化层

池化层通过减少特征图的尺寸来降低计算量和参数数量&#xff0c;同时增加模型的平移不变性和鲁棒性。汇聚层的主要优点之一是减轻卷积层对位置的过度敏感。 1 最大汇聚层、平均汇聚层 汇聚层和卷积核一样&#xff0c;是在输入图片上进行滑动计算&#xff0c;但是不同于卷积层的…

深度学习笔记10-多分类

多分类和softmax回归 在多分类问题中&#xff0c;一个样本会被划分到三个或更多的类别中&#xff0c;可以使用多个二分类模型或一个多分类模型&#xff0c;这两种方式解决多分类问题。 1.基于二分类模型的多分类 直接基于二分类模型解决多分类任务&#xff0c;对于多分类中的每…

接口测试面试题及答案(后续)

一、你们什么时候测试接口 一般有需求就会做&#xff0c;后台的接口开发好&#xff0c;就可以开始测。例外&#xff0c;如果增加了新需求&#xff0c;也要做接口测试&#xff0c;还有就是开发对后台的接口做了修改&#xff0c;交互逻辑发生变化&#xff0c;我们也要重新对接口…

【SpringCloud】Nacos微服务注册中心

微服务的注册中心 注册中心可以说是微服务架构中的"通讯录"&#xff0c;它记录了服务和服务地址的映射关系 。在分布式架构中&#xff0c; 服务会注册到这里&#xff0c;当服务需要调⽤其它服务时&#xff0c;就从这里找到服务的地址&#xff0c;进行调用。 注册中心…

服务器数据恢复—分区结构被破坏的reiserfs文件系统数据恢复案例

服务器数据恢复环境&#xff1a; 一台服务器中有一组由4块SAS硬盘组建的RAID5阵列&#xff0c;上层安装linux操作系统统。分区结构&#xff1a;boot分区LVM卷swap分区&#xff08;按照顺序&#xff09;&#xff0c;LVM卷中划分了一个reiserfs文件系统作为根分区。 服务器故障…

Linux下的WatchDog

看门狗&#x1f415; 看门狗简介 看门狗定时器&#xff08;Watchdog Timer&#xff09;是一种定时器&#xff0c;用于检测系统是否正常运行。如果系统在规定时间内没有向看门狗定时器发送复位信号&#xff0c;看门狗定时器就会产生复位信号&#xff0c;使系统复位。看门狗定时…

机器学习(五)——支持向量机SVM(支持向量、间隔、正则化参数C、误差容忍度ε、核函数、软间隔、SVR、回归分类源码)

目录 关于1 间隔与支持向量2 对偶问题3 核函数4 软间隔与正则化5 支持向量回归6 核方法X 案例代码X.1 分类任务X.1.1 源码X.1.2 数据集&#xff08;鸢尾花数据集&#xff09;X.1.3 模型效果 X.2 回归任务X.2.1 源码X.2.2 数据集&#xff08;加州房价数据&#xff09;X.2.3 模型…

25国考照片处理器使用流程图解❗

1、打开“国家公务员局”网站&#xff0c;进入2025公务员专题&#xff0c;找到考生考务入口 2、点击下载地址 3、这几个下载链接都可以 4、下载压缩包 5、解压后先看“使用说明”&#xff0c;再找到“照片处理工具”双击。 6、双击后会进入这样的界面&#xff0c;点击&…

几个docker可用的镜像源

几个docker可用的镜像源 &#x1f490;The Begin&#x1f490;点点关注&#xff0c;收藏不迷路&#x1f490; sudo rm -rf /etc/docker/daemon.json sudo mkdir -p /etc/dockersudo tee /etc/docker/daemon.json <<-EOF {"registry-mirrors": ["https://d…

Vue 项目中为何选择 TSX 而非传统 .vue 文件

近年来&#xff0c;Vue 项目中使用 TSX&#xff08;TypeScript JSX&#xff09;的写法逐渐增多&#xff0c;尤其在 TypeScript 项目中。 1. TSX 与 Vue 的结合背景 1、Vue 3 和 TypeScript Vue 3 从设计之初便更好地支持 TypeScript。Vue 3 使用了 TypeScript 重写核心&…

【SpringBoot】18 上传文件到数据库(Thymeleaf + MySQL)

Git仓库 https://gitee.com/Lin_DH/system 介绍 使用 Thymeleaf 写的页面&#xff0c;将&#xff08;txt、jpg、png&#xff09;格式文件上传到 MySQL 数据库中。 依赖 pom.xml <!-- https://mvnrepository.com/artifact/com.mysql/mysql-connector-j --><depende…

[VUE]框架网页开发1 本地开发环境安装

前言 其实你不要看我的文章比较长&#xff0c;但是他就是很长&#xff01;步骤其实很简单&#xff0c;主要是为新手加了很多解释&#xff01; 步骤一&#xff1a;下载并安装 Node.js 访问 Node.js 官网&#xff1a; Node.js — Download Node.js 下载 Windows 64 位版本&…

canal1.1.7使用canal-adapter进行mysql同步数据

重要的事情说前面&#xff0c;canal1.1.8需要jdk11以上&#xff0c;大家自行选择&#xff0c;我这由于项目原因只能使用1.1.7兼容版的 文章参考地址&#xff1a; canal 使用详解_canal使用-CSDN博客 使用canal.deployer-1.1.7和canal.adapter-1.1.7实现mysql数据同步_mysql更…