C++条件变量condition_variable

news2024/9/21 10:33:50

一、问题

假设没有条件变量,对于一个生产者消费者问题,消费线程在得知队列中没有产品时,将阻塞自己。生产者线程可以给队列中放入产品,但是没有办法激活消费者线程,而消费者线程处于阻塞状态也没有办法自己激活自己。如果消费者线程使用忙等的方式,通过不断地查询来判断是否有产品,将大量的浪费CPU时间。消费者线程也可以使用睡眠+查询的方式,即发现队列中没有产品时,sleep一段时间,然后再查询。问题是睡眠多长时间?时间太长,实时性不好,时间太短,还是浪费CPU时间。

二、介绍

针对类似的场景,我们推荐您用条件变量来实现,头文件<condition_variable>。和互斥锁、信号量类似,条件变量本质也是一个全局变量,用于多线程之间关于共享数据状态变化的通信。当一个动作需要另外一个动作完成时才能进行,即:当一个线程的行为依赖于另外一个线程对共享数据状态的改变时,这时候就可以使用条件变量。

一个条件变量可以阻塞多个线程,这些线程会组成一个等待队列。当条件成立时,条件变量可以解除线程的“被阻塞状态”。也就是说,条件变量可以完成以下两项操作:

1、阻塞线程,直至接收到“条件成立”的信号;
2、向等待队列中的一个或所有线程发送“条件成立”的信号,解除它们的“被阻塞”状态。

为了避免多线程之间发生“抢夺资源”的问题,条件变量在使用过程中必须和一个互斥锁搭配使用。

三、notify_one()notify_all()

notify_one()与notify_all()常用来唤醒阻塞的线程。

notify_one():因为只唤醒等待队列中的第一个线程;不存在锁争用,所以能够立即获得锁。其余的线程不会被唤醒,需要等待再次调用notify_one()或者notify_all()。

notify_all():会唤醒所有等待队列中阻塞的线程,存在锁争用,只有一个线程能够获得锁。那其余未获取锁的线程会继续尝试获得锁(类似于轮询),而不会再次阻塞。当持有锁的线程释放锁时,这些线程中的一个会获得锁。而其余的会接着尝试获得锁。
 

四、实例

条件变量通常有wait和notify两个动作,wait用于阻塞挂起线程A,直到另一个线程B通过notify唤醒线程A,唤醒后线程A会继续运行。这里使用消费者,生产者模型代码

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

std::mutex mut;
std::condition_variable cv;
std::vector<int> vec{};

// 消费者
void Consumer()
{
    std::unique_lock<std::mutex> lock(mut);
    while (vec.empty()) {
        cv.wait(lock); //等待线程
    }
    std::cout << "consumer " << vec.size() << "\n";
}

//生产者
void Produce()
{
    std::unique_lock<std::mutex> lock(mutex);
    vec.push_back(1);
    cv.notify_all();// 唤醒线程
    std::cout << "produce \n";
}

int main()
{
    std::thread thread1(Consumer);
    thread1.detach(); // 主线程和子线程相互分离,互不干扰
    Produce();
    system("pause");
    return 0;
}

参考:

条件变量的坑 - 知乎
C++11条件变量:notify_one()与notify_all()的区别_吃素的施子的博客-CSDN博客

C++11(六) 条件变量(condition_variable) - 知乎

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

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

相关文章

RocketMQ 领域模型概述

本文为您介绍 Apache RocketMQ 的领域模型。 Apache RocketMQ 是一款典型的分布式架构下的中间件产品&#xff0c;使用异步通信方式和发布订阅的消息传输模型。通信方式和传输模型的具体说明&#xff0c;请参见下文通信方式介绍和消息传输模型介绍。 Apache RocketMQ 产品具备…

IOS开发指南之自定义TableViewCell使用

演示效果: 1.自定义TableViewCell创建 File->new->File... 在iOS模板中选择Empty来创建一个空的XIB文件,然后点击下一步 输入XIB文件名Cell,然后点击Create创建 创建XIB文件成功后如下: 同时按钮Shift+command+L弹出库,然后输入 table筛选,选择Table View Cell 拖到下…

一文通透spring的初始化

简述 今天重点分析ApplicationContext初始化时做的事情&#xff0c;我们都只到spring是个IOC和AOP容器&#xff0c;那再我们new一个ApplicationContext&#xff0c;spring内部都做了什么&#xff1f;怎么实现的IOC和AOP&#xff1f; 比如说下面这段代码 Configuration Compon…

计组 第二章 数据的表示与运算 2.1 数制与编码 知识点整理

2.1 数制与编码 二进制转八进制&#xff1a;3位一组&#xff0c;高位补0 二进制转十六进制&#xff1a;4位一组&#xff0c;高位补0 任意进制转十进制&#xff08;按权展开法&#xff09;&#xff1a;数码与权值相乘&#xff0c;再相加 十进制转化为任意进制数&#xff08;基…

全面接入:ChatGPT杀进10个商业应用,让AI替你打工

ChatGPT狂飙160天&#xff0c;世界已经不是两个月前的样子。 新建了一个网站 https://ai.weoknow.com/ 每天给大家更新可用的国内可用chatGPT资源 ChatGPT API已开放60多天。世界已经不是两个月前的样子了。 微软联合创始人比尔盖茨&#xff08;BillGates&#xff09;将GPT称…

一、预约挂号详情

文章目录 一、预约挂号详情1、需求分析 2、api接口2.1 添加service接口2.2 添加service接口实现2.2.1 在ScheduleServiceImpl类实现接口2.2.2 在获取科室信息 2.3 添加controller方法 3、前端3.1封装api请求3.2 页面展示 二、预约确认1、api接口1.1 添加service接口1.2 添加con…

FastRcnn理论合集

FastRcnn理论合集 Rcnn 论文原著 Rich feature hierarchies for accurate object detection and semantic segmentation R-CNN可以说是利用深度学习进行目标检测的开山之作。作者Ross Girshick多次在PASCAL VOC的目标检测竞赛中折桂&#xff0c;曾在2010年带领团队获得终身成就…

【P29】JMeter IF 控制器(If Controller)

文章目录 一、IF 控制器&#xff08;If Controller&#xff09;参数说明二、测试计划设计2.1、groovy 写法2.2、javaScript 写法2.3、jexl3 写法 一、IF 控制器&#xff08;If Controller&#xff09;参数说明 可以控制其下面的子/后代元素是否执行&#xff1b;如果为 true 则…

CSDN问答机器人

文章目录 前言一、背景二、总体流程三、构建知识库四、粗排五、精排六、Prompt总结相关博客 前言 先看结果: 已经连续很多周获得了第二名(万年老二), 上周终于拿了一回第一, 希望继续保持. &#x1f601; 这是今天的榜单, 采纳的数量相对较少, 之前基本上维持在100 重点说明…

数字韧性助力金融科技行稳致远 同创永益亮相2023双态IT武汉樱花论坛

2023年4月7日&#xff0c;由ITSS数据中心运营管理组DCMG指导&#xff0c;双态IT论坛主办的以“分布式架构和云原生时代的运维软件进化”为主题的“双态IT武汉樱花论坛”在武汉成功举办&#xff0c;共有来自银行、保险、证券等行业用户及企业代表近百人参会。 云原生时代下&am…

【Linux】-yum的使用

&#x1f496;作者&#xff1a;小树苗渴望变成参天大树 ❤️‍&#x1fa79;作者宣言&#xff1a;认真写好每一篇博客 &#x1f4a8;作者gitee:gitee &#x1f49e;作者专栏&#xff1a;C语言,数据结构初阶,Linux,C 如 果 你 喜 欢 作 者 的 文 章 &#xff0c;就 给 作 者 点…

某生存游戏玩家属性值分析

0x01 背景 这是一款丧尸生存的多人沙盒类游戏&#xff0c;角色在废墟之城内不断的搜刮&#xff0c;强化自己的装备和建造设施来抵御丧尸的无休止攻击&#xff0c;记住&#xff0c;这是一款团队合作游戏&#xff0c;你面对的丧尸随时可能夺走你的性命&#xff01; 0x02 玩家结…

【C++ Primer Plus】基础知识

C站的小伙伴们&#xff0c;大家好呀&#xff01;我最近开始阅读学习《C Primer Plus》这本书&#xff0c;在这里和大家一起分享。 下面是本书的第二章《开始学习C》 开始学习C 进入Cmain&#xff08;&#xff09;函数C注释C预处理器和iostream文件头文件名名称空间使用count进行…

【Linux专区】 Linux is not unix | Linux发展史 | Linux应用现状

&#x1f49e;&#x1f49e;欢迎来到 Claffic 的博客&#x1f49e;&#x1f49e; &#x1f449; 专栏&#xff1a;《Linux专区》&#x1f448; 前言&#xff1a; 上次提前带大家搭建了Linux的环境&#xff0c;其实之前应该还有一步的&#xff0c;就是向大家介绍Linux发展史&…

HNU-电路与电子学-小班3

第三次讨论 1 、直接用晶体管而不是逻辑门实现异或门&#xff0c;并解释这个电路是如何工作的。 &#xff08;6个 MOS 管构成&#xff09; 2 、通信双方约定采用 7 位海明码进行数据传输。请为发送方设计海明码校验位 生成电路&#xff0c;采用功能块和逻辑门为接收方设计海…

SCMA基本原理介绍

SCMA: Sparse Code Multiple Access SCMA基本原理 我们考虑一个同步&#xff08;synchronous&#xff09;的SCMA系统&#xff0c; 含1个基站&#xff08;Base Station, BS&#xff09;&#xff1b; J J J个用户&#xff08;so called layers&#xff09;&#xff1b;K个OFDM…

算法练习-2:送外卖

n 个小区排成一列&#xff0c;编号为从 0 到 n-1 。一开始&#xff0c;美团外卖员在第0号小区&#xff0c;目标为位于第 n-1 个小区的配送站。 给定两个整数数列 a[0]~a[n-1] 和 b[0]~b[n-1] &#xff0c;在每个小区 i 里你有两种选择&#xff1a; 1) 选择a&#xff1a;向前 a[…

shiro环境搭建

源码部署 这种方法相对复杂&#xff0c;如果不需要分析源码直接用docker就行 前置条件&#xff1a;Maven Ideal Tomcat 下载方式1&#xff1a;https://codeload.github.com/apache/shiro/zip/shiro-root-1.2.4&#xff0c;然后将文件夹导入ideal下载方式2&#xff1a;将shiro…

装饰者模式-java实现

的简介 装饰模式又称为“包装(Wrapper)模式”&#xff0c;以对客户端透明的方式扩展对象的功能&#xff0c;是继承关系的一个替代方案。动态地给对象添加一些额外地职责&#xff0c;就增加功能而言&#xff0c;装饰模式比生成子类更加灵活。 一般来说&#xff0c;一些特殊场景…

C++ new和delete详解

文章目录 1、 C C C内存分布2、 C C C内存管理方式3、 n e w new new 和 d e l e t e delete delete 底层实现4、定位 n e w new new表达式&#xff08;了解&#xff09;5、 m a l l o c 、 f r e e 和 n e w 、 d e l e t e malloc、free和new、delete malloc、free和new、de…