C++11并发与多线程笔记(8) condition_variable、wait、notify_one、notify_all

C++11并发与多线程笔记(8) condition_variable、wait、notify_one、notify_all

  • 1、条件变量condition_variable、wait、notify_one、notify_all
    • 1.1 std::condition_variable
    • 1.2 wait()
    • 1.3 notify_one()
    • 1.4 notify_all()
  • 2、深入思考

1、条件变量condition_variable、wait、notify_one、notify_all

1.1 std::condition_variable

实际上是一个,是一个和条件相关的类,说白了就是等待一个条件达成。

1.2 wait()

  1. wait()只有一个参数(相当于第二个参数为true)
    void wait( std::unique_lock<std::mutex>& lock )

    先解锁之前获得的互斥量mutex,然后阻塞当前的执行线程。把当前线程添加到等待线程列表中,该线程会持续阻塞直到被 ** notify_one()** 唤醒。被唤醒后,该thread会尝试重新获取互斥量mutex,获取到mutex后执行后面的动作。

  2. wait()有两个参数
    void wait( std::unique_lock<std::mutex>& lock, Predicate pred )
    设置了第二个参数 Predicate, 只有当pred为false时,wait才会阻塞当前线程。这情况下,线程被唤醒后,先获取mutex,再次判断pred的值。如果pred为false,则会释放mutex并重新阻塞在wait

wait() 效果就是把锁释放并阻塞,以便于其他人去获取,不然条件不满足时,一遍遍去询问,太浪费时间。

1.3 notify_one()

随机唤醒一个等待的线程

notify_one() 唤醒一个线程不一定能成功,如果要唤醒的线程不在wait()处等待,将没有唤醒效果。

1.4 notify_all()

唤醒所有等待的线程

#include <iostream>
#include <thread>
#include <mutex>
#include <list>
using namespace std;list<int> test_list;
mutex myMutex1;//创建一个互斥量condition_variable my_cond;//生成一个条件变量对象
void in_list() {for (int num = 0; num < 100000; num++) {{cout << "插入数据:" << num << endl;unique_lock<mutex> myUniLock(myMutex1);//操作事务test_list.push_back(num);my_cond.notify_one();//我们尝试把wait()的线程唤醒,执行完这行,那么out_list()里边的wait就会被唤醒}}
}void out_list() {int command = 0;while (true) {unique_lock<mutex> myUniLock(myMutex1);//如果第二个参数lambda表达式返回值是false,那么wait()将解锁互斥量,并堵塞到本行,my_cond.wait(myUniLock, [=] {//一个lambda就是一个可调用的对象(函数)if (!test_list.empty())return true;return false;});//流程只要走到这里来,这个互斥锁一定是锁着的command= test_list.front();//返回第一个元素,但不检查元素是否存在test_list.pop_front();//移除第一个元素,但不返回myUniLock.unlock();//可以提前解锁,以免锁住太长时间//执行其它非共享数据业务cout << "out_list()执行,取出一个元素" << command << endl;}
}
int main()
{thread in_thread(in_list);thread out_thread(out_list);out_thread.join();in_thread.join();cout << "I love China!" << endl;return 0;
}

2、深入思考

上面的代码可能导致出现一种情况:
因为out_list()与in_list()并不是一对一执行的,所以当程序循环执行很多次以后,可能在test_list中已经有了很多消息,但是,out_list还是被唤醒一次只处理一条数据。这时可以考虑把out_list多执行几次,或者对in_list进行限流

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

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

相关文章

JS内存泄漏

JS内存泄漏 1.意外的全局变量 全局变量的生命周期很长&#xff0c;直到页面关闭&#xff0c;它都存活&#xff0c;所以全局变量上的内存一直都不会被回收 当全局变量使用不当&#xff0c;没有及时回收&#xff08;手动赋值null&#xff09;&#xff0c;或者拼写错误等将某个变…

[Machine Learning] decision tree 决策树

&#xff08;为了节约时间&#xff0c;后面关于机器学习和有关内容哦就是用中文进行书写了&#xff0c;如果有需要的话&#xff0c;我在目前手头项目交工以后&#xff0c;用英文重写一遍&#xff09; &#xff08;祝&#xff0c;本文同时用于比赛学习笔记和机器学习基础课程&a…

【算法学习】两数之和II - 输入有序数组

题目描述 原题链接 给你一个下标从 1 开始的整数数组 numbers &#xff0c;该数组已按 非递减顺序排列 &#xff0c;请你从数组中找出满足相加之和等于目标数 target 的两个数。如果设这两个数分别是 numbers[index1] 和 numbers[index2] &#xff0c;则 1 < index1 < …

Springboot MultipartFile文件上传与下载

yml文件配置是否可以上传及上传附件大小 servlet:multipart:# 允许文件上传enabled: true# 单个文件大小max-file-size: 20MB# 设置总上传的文件大小max-request-size: 50MB /*** param files* param request* Description 上传文件* Throws* Return java.util.List* Date 202…

南大通用数据库(Gbase 8s) 创建UDR外部函数

一、在使用 date_format、from_unixtime、to_days、yearweek 函数时&#xff0c;Gbase 8s 数据库不支持&#xff0c;可以使用创建 UDR 外部函数来实现 二、登录命令控制台或者使用 navicat 连接 Gbase 数据库 这里使用 navicat &#xff0c;点击新增连接选择 PostGreSql 驱动…

动手学深度学习—卷积神经网络LeNet(代码详解)

1. LeNet LeNet由两个部分组成&#xff1a; 卷积编码器&#xff1a;由两个卷积层组成&#xff1b;全连接层密集块&#xff1a;由三个全连接层组成。 每个卷积块中的基本单元是一个卷积层、一个sigmoid激活函数和平均汇聚层&#xff1b;每个卷积层使用55卷积核和一个sigmoid激…

LeetCode--HOT100题(35)

目录 题目描述&#xff1a;23. 合并 K 个升序链表&#xff08;困难&#xff09;题目接口解题思路1代码解题思路2代码 PS: 题目描述&#xff1a;23. 合并 K 个升序链表&#xff08;困难&#xff09; 给你一个链表数组&#xff0c;每个链表都已经按升序排列。 请你将所有链表合…

UDP 的报文结构以及注意事项

UDP协议 1.UDP协议端格式 1.图中的16位UDP长度,表示整个数据报(UDP首部UDP数据)的最大长度 2.若校验和出错,会直接丢弃 2.UDP的报文结构 UDP报文主体分为两个部分:UDP报头(占8个字节)UDP载荷/UDP数据 1.源端口号 16位,2个字节 2.目的端口号 16位,2个字节 3.包长度 指示了…

sd-webui安装comfyui扩展

文章目录 导读ComfyUI 环境安装1. 安装相关组件2. 启动sd-webui3. 访问sd-webui 错误信息以及解决办法 导读 这篇文章主要给大家介绍如何在sd-webui中来安装ComfyUI插件 ComfyUI ComfyUI是一个基于节点流程式的stable diffusion的绘图工具&#xff0c;它集成了stable diffus…

两个list如何根据一个list中的属性去过滤掉另一个list中不包含这部分的属性,用流实现

你可以使用Java 8的流来实现这个功能。假设你有两个包含对象的List&#xff0c;每个对象有一个属性&#xff0c;你想根据一个List中的属性值来过滤掉另一个List中不包含这个属性值的对象。下面是一种使用流的方式来实现这个功能 import java.util.ArrayList; import java.util…

什么是闭包(closure)?为什么它在JavaScript中很有用?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 闭包&#xff08;Closure&#xff09;是什么&#xff1f;⭐ 闭包的用处⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅&…

IO流面试题

题目一&#xff1a; 在磁盘中新建一个文件(如果目录结构不存在&#xff0c;则创建目录) 文件名&#xff1a;data.txt 文件日录&#xff1a;C:\demo\test\files (盘符不限) linux目录~/demo/test/files 题二 在新建的data.txt中添加如下内容&#xff1a; 张三,测试,2019-02-18 …

windows10 安装WSL2, Ubuntu,docker

AI- 通过docker开发调试部署ChatLLM 阅读时长&#xff1a;10分钟 本文内容&#xff1a; window上安装ubuntu虚拟机&#xff0c;并在虚拟机中安装docker&#xff0c;通过docker部署数字人模型&#xff0c;通过vscode链接到虚拟机进行开发调试.调试完成后&#xff0c;直接部署在云…

优漫动游零基础如何学习好UI设计

智能时代的来临&#xff0c;很多企业都越来越注重用户体验这一块&#xff0c;想要有一个吸引用户的好页面&#xff0c;UI设计师岗位不可或缺&#xff0c;如今越来越多的人想要学习UI设计技术&#xff0c;那么对于零基础小白如何学习好UI设计呢? 零基础小白如何学习好UI设计…

变更通知在开源SpringBoot/SpringCloud微服务中的最佳实践

目录导读 变更通知在开源SpringBoot/SpringCloud微服务中的最佳实践1. 什么是变更通知2. 变更通知的场景分析3. 变更通知的技术方案3.1 变更通知的技术实现方案 4. 变更通知的最佳实践总结5. 参考资料 变更通知在开源SpringBoot/SpringCloud微服务中的最佳实践 1. 什么是变更通…

Ubuntu在自己的项目中使用pcl

1、建立一个文件夹&#xff0c;如pcl_demos&#xff0c;里面建立一个.cpp文件和一个cmake文件 2、打开终端并进入该文件夹下&#xff0c;建立一个build文件夹存放编译的结果并进入该文件夹 3、对上一级进行编译 cmake .. 4、生成可执行文件 make 5、运行该可执行文件 6、可视…

最强自动化测试框架Playwright(30)-JS句柄

在 Playwright 中&#xff0c;JSHandle 是一个表示浏览器中 JavaScript 对象的类。它提供了与网页中的 JavaScript 对象进行交互和操作的方法。 可以通过调用 Playwright中的 evaluateHandle 或 evaluate 方法来获取 JSHandle from playwright.sync_api import sync_playwrig…

微服务中间件-分布式缓存Redis

分布式缓存 a.Redis持久化1) RDB持久化1.a) RDB持久化-原理 2) AOF持久化3) 两者对比 b.Redis主从1) 搭建主从架构2) 数据同步原理&#xff08;全量同步&#xff09;3) 数据同步原理&#xff08;增量同步&#xff09; c.Redis哨兵1) 哨兵的作用2) 搭建Redis哨兵集群3) RedisTem…

金融语言模型:FinGPT

项目简介 FinGPT是一个开源的金融语言模型&#xff08;LLMs&#xff09;&#xff0c;由FinNLP项目提供。这个项目让对金融领域的自然语言处理&#xff08;NLP&#xff09;感兴趣的人们有了一个可以自由尝试的平台&#xff0c;并提供了一个与专有模型相比更容易获取的金融数据。…

Java根据List集合中的一个字段对集合进行去重

利用HashSet 创建了一个HashSet用于存储唯一的字段值&#xff0c;并创建了一个新的列表uniqueList用于存储去重后的对象。遍历原始列表时&#xff0c;如果字段值未在HashSet中出现过&#xff0c;则将其添加到HashSet和uniqueList中。 List<Person> originalList new Ar…