C++11条件变量condition_variable

文章目录

    • 前言
    • 正文
      • 等待
      • 通知
      • 注意事项
    • 结尾

前言

条件变量用于多线程中,其作用是在多线程间实现线程的等待、唤醒和通知机制,常配合互斥锁(std::mutex)一起使用。它主要用于解决数据竞争问题>。

正文

条件变量只有五个函数:

方法作用
notify_one()通知一个等待的线程
notify_all()通知所有等待的线程
wait()阻塞该线程,直到条件变量被唤醒
wait_for()阻塞该线程,直到条件变量被唤醒或者到达指定时限时长后
wait_until()阻塞该线程,直到条件变量被唤醒或者到达指定时间点后

条件变量的方法分为两种:通知等待,我们一个个来说:

等待

wait()部分的就是等待函数,它接收两个参数:

template<class Predicate>
void wait(std::unique_lock<std::mutex>& lock, Predicate pred);void wait(std::unique_lock<std::mutex>& lock);

它有两个版本,我们先说最简单的版本,它只有一个参数:

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

它接收一个unique_lock作为参数。当程序运行到wait()这一行的时候,程序必定阻塞,只有等到通知之后才会继续运行,这个状态我们也称之为睡眠
那么有两个参数的呢?它的第二个参数是一个谓词,这里我们能够理解为一个函数,通常是使用lambda表达式。当wait()接到通知的时候,执行这个谓词,若是返回的结果为true,就获取锁的所有权,执行接下来的语句;若是为false,它就重新进入睡眠状态,继续阻塞线程,等待下一次通知的出现。
所以谓词的声明也等同于:

bool pred();

那么其他的wait就不多说了。

通知

通知有两个函数,notify_one()和notify_all(),前者只通知一个线程,而后者则会通知所有线程,在通知之后,被通知的线程会判断是否满足条件函数的要求,若是符合要求,则执行其后面的函数,若是不满足要求,则回到睡眠状态。

注意事项

notify_one() 和 notify_all() 的调用都不会立即执行实际的唤醒操作。相反,它们只是在条件变量上设置了一个唤醒标志,并在互斥锁释放之后,等待其他线程重新获取互斥锁时才会实际执行唤醒操作。
也就是说:只有能获取到互斥锁的时候才会进行唤醒,并让它去争抢互斥锁。

结尾

条件变量的内容其实很少,也比较好理解,问题在怎么去使用它。
这里我给出一段代码,这段代码是一个简单的消息队列,也是个非常简单的生产者消费者队列,实现了一个消息的发送和接收功能,配合代码食用效果更佳(在重要的地方我都写了注释,希望能够帮助大家理解):

#include <iostream>
#include <thread>
#include <memory>
#include <string>
#include <condition_variable>
#include <list>
#include <atomic>std::mutex mtx;
std::condition_variable cv;
std::list<std::string> msg;// 读取数据
void read_thread(){while(true){std::unique_lock<std::mutex> lock(mtx);// 阻塞等待消息(并且解锁)// 有消息再执行,没消息不执行cv.wait(lock,[&](){ return !msg.empty(); });// 获取到互斥锁std::cout << "收到消息,解析中:" << std::endl;std::cout << msg.front() << std::endl;msg.pop_front();}
}// 写入数据
void write_thread(){std::cout << "请输入需要发送的数据:" << std::endl;std::string input;while(true){if(std::cin >> input){std::unique_lock<std::mutex> lock(mtx);msg.push_back(input);std::cout << "数据成功输入" << std::endl;// 通知read线程,有消息可以接收cv.notify_all();}}
}int main(){std::thread write_(write_thread);write_.detach();std::thread read_(read_thread);read_.detach();// 阻塞主线程while(true);return 0;
}

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

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

相关文章

PyQt6 QCalendarWidget日历控件

​锋哥原创的PyQt6视频教程&#xff1a; 2024版 PyQt6 Python桌面开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili2024版 PyQt6 Python桌面开发 视频教程(无废话版) 玩命更新中~共计39条视频&#xff0c;包括&#xff1a;2024版 PyQt6 Python桌面开发 视频教程(无废话…

快速实现入门HarmonyOS开发

本文档适用于HarmonyOS应用开发的初学者。编写两个简单的页面&#xff0c;实现在第一个页面点击按钮跳转到第二个页面。开始前&#xff0c;请参考下载与安装软件、配置开发环境和运行HelloWorld&#xff0c;完成开发工具的安装和开发环境的配置。 开发Ability 概述&#xff1…

Python 日期时间模块详解(datetime)

文章目录 1 概述1.1 datetime 类图1.2 类描述 2 常用方法2.1 获取当前日期时间&#xff1a;now()、today()、time()2.2 日期时间格式化&#xff1a;strftime()2.3 日期时间大小比较&#xff1a;>、、<2.4 日期时间间隔&#xff1a;- 3 扩展3.1 Python 中日期时间格式化符…

混合预编码(Hybrid Precoding)的全连接结构与子连接结构

A Survey on Hybrid Beamforming Techniques in 5G: Architecture and System Model Perspectives 全连接结构的混合预编码 子连接结构的混合预编码 Alternating Minimization Algorithms for HybridPrecoding in Millimeter Wave MIMO Systems

UE Websocket笔记

参考链接 [UE4 C入门到进阶]12.Websocket网络通信 - 哔哩哔哩 包含怎么用Nodejs 写测试服务器 UE4_使用WebSocket和Json&#xff08;上&#xff09; - 知乎 包含Python写测试服务器 UE4_使用WebSocket和Json&#xff08;下&#xff09; - 知乎 示例代码 xxx.Build.cs"W…

【React】使用react hooks实现评论示例

实现功能 1、渲染评论列表 2、删除评论 3、渲染导航栏和高亮 4、评论列表排序功能 5、获取评论 6、点击发布按钮发布评论 7、清空输入框 8、重新聚焦 实现代码 1、需要引入 import React, { useRef, useState } from react import avatar from "../logo.png" //头…

[动态规划及递归记忆搜索法]2.插入乘号

插入乘号 题目描述 给定一个非负整数&#xff0c;用k个乘号将其分割&#xff0c;使得乘积最大。 例如&#xff1a;在整数12345中插入两个乘号&#xff0c;有以下插入法&#xff1a; 1*2*345 1*23*45 1*234*5 12*3*45 12*34*5 123*4*5 其中最大值是123*4*5 2460 关于输入 一…

前端小技巧: 面向切面编程在前端代码中的应用

面向切面编程 面向切面编程在java中提出这类概念但是在js没有束缚和约定&#xff0c;只需要按编程思想来实现原理在js中使用function或class实现面向切面编程 面向切面概念 AOP (Aspect Oriented Programming) 面向切面编程主要实现目的是针对业务处理过程中的切面进行提取&…

第18章:随堂复习与企业真题(JDK8-17新特性)

第18章&#xff1a;随堂复习与企业真题&#xff08;JDK8-17新特性&#xff09; 一、随堂复习 1. JDK新特性的概述 几个重要的版本 jdk 5.0 / jdk 8.0 &#xff1a;里程碑式的版本jdk9.0 开始每6个月发布一个新的版本LTS : jdk8 、 jdk 11 、 jdk 17 如何学习新特性 > 角…

Android安全学习路标

1. Android操作系统基础知识 首先&#xff0c;你需要建立坚实的Android操作系统基础知识&#xff0c;包括Android架构、进程和内存管理、应用组件和权限模型等基本概念。 2. 安全防范理论 学习关于安全防范理论的基础知识&#xff0c;包括常见的威胁模型、攻击类型和安全风险…

Python-猜数字游戏

&#x1f388; 博主&#xff1a;一只程序猿子 &#x1f388; 博客主页&#xff1a;一只程序猿子 博客主页 &#x1f388; 个人介绍&#xff1a;爱好(bushi)编程&#xff01; &#x1f388; 创作不易&#xff1a;喜欢的话麻烦您点个&#x1f44d;和⭐&#xff01; &#x1f388;…

免费的AI改写文案软件,热门AI改写文案软件【2024】

在数字化时代&#xff0c;文案创作变得更为便捷&#xff0c;其中AI改写文案软件的兴起为写作者们带来了全新的创作体验。这些工具通过智能算法和自然语言处理技术&#xff0c;能够快速改写文本&#xff0c;提高创作效率。本文将深入探讨AI改写文案软件的现状&#xff0c;介绍一…

LeetCode题:174. 地下城游戏

目录 一、题目要求 二、解题思路 &#xff08;1&#xff09;状态表示 &#xff08;2&#xff09;状态转移方程 &#xff08;3&#xff09;初始化dp表 &#xff08;4&#xff09;填表顺序 &#xff08;5&#xff09;返回值 三、代码 一、题目要求 174. 地下城游戏 恶魔们…

swagger入门

swagger入门 pom依赖 不用专门导入swagger 因为springboot已经将它集成了 org.springframework.boot spring-boot-starter com.github.xiaoymin knife4j-spring-boot-starter Swagger配置类 Configuration public class SwaggerConfig { // 创建并配置Docket Bean&#xf…

snakeyaml编辑yaml文件并覆盖注释

文章目录 前言技术积累实战演示1、引入maven依赖2、覆盖注释工具类3、snakeyaml工具类4、测试用例5、测试效果展示 写在最后 前言 最近在做一个动态整合框架的项目&#xff0c;需要根据需求动态组装各个功能模块。其中就涉及到了在application.yaml中加入其他模块的配置&#…

TCP传输层详解(计算机网络复习)

介绍&#xff1a;TCP/IP包含了一系列的协议&#xff0c;也叫TCP/IP协议族&#xff0c;简称TCP/IP。该协议族提供了点对点的连接机制&#xff0c;并将传输数据帧的封装、寻址、传输、路由以及接收方式都予以标准化 TCP/IP的分层模型 在讲TCP/IP协议之前&#xff0c;首先介绍一…

力扣贪心题解 跳跃游戏

55. 跳跃游戏 - 力扣&#xff08;LeetCode&#xff09; 给你一个非负整数数组 nums &#xff0c;你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标&#xff0c;如果可以&#xff0c;返回 true &#xff1b…

信息系统开发方法

企业信息系统对于企业信息化的重要意义是不言而喻的。从实际运行的效果来看&#xff0c;有些信息系统运行得很成功&#xff0c;取得了巨大的经济效益和社会效益&#xff1b;但也有些信息系统效果并不显著&#xff0c;甚至还有个别信息系统开始时还能正常运行&#xff0c;可时间…

广州数字孪生赋能工业制造,加速推进制造业数字化转型

广州数字孪生赋能工业制造&#xff0c;加速推进制造业数字化转型。数字孪生系统基于历史数据、实时数据&#xff0c;采用人工智能、大数据分析等新一代信息技术对物理实体的组成、特征、功能和性能进行数字化定义和建模。通过构建在信息世界对物理实体的等价映射&#xff0c;对…

Axure官方软件安装、汉化保姆级教程(带官方资源下载)

1.下载汉化包 百度云链接&#xff1a;https://pan.baidu.com/s/1lluobjjBZvitASMt8e0A_w?pwdjqxn 提取码&#xff1a; jqxn 2.解压压缩包 3.安装Axure 进行安装 点击next 打勾&#xff0c;然后next, 默认是c盘&#xff0c;修改成自己的文件夹&#xff08;不要什么都放c盘里…