Linux 线程同步——条件变量

news/2024/5/9 22:55:27/文章来源:https://blog.csdn.net/NuYoaH502329/article/details/132422424

一、条件变量的概念

如果说互斥锁是用于同步线程对共享数据的访问的话,那么条件变量则是用于在线程之间同步共享数据的值。条件变量提供了一种线程间的通知机制:当某个共享数据达到某个值的时候,唤醒等待这个共享数据的线程。如下图所示:

在这里插入图片描述

二、条件变量相关函数

1.pthread_cond_init()初始化条件变量

在这里插入图片描述

参数解释:

第一个参数cond:条件变量
第二个参数attr:条件变量属性,通常传NULL,表示使用默认属性

2.pthread_cond_wait()等待条件变量满足

在这里插入图片描述

功能:阻塞等待一个条件变量(等待唤醒)并解除相应的锁资源

参数解释:
第一个参数cond:条件变量
第二个参数mutex:是用于保护条件变量的互斥锁,以确保pthread_cond_wait操作的原子性。在调用pthread_cond_wait之前必须确保互斥锁mutex已经加锁,否则将会出现多个线程同时要进入等待队列的情况导致不可预期的结果。pthread_cond_wait在执行时,首先把调用线程放入条件变量的等待队列中,然后将互斥锁解锁。从pthread_cond_wait开始执行到其调用线程被放入条件变量的等待队列之间的这段时间内,pthread_cond_signal和pthread_cond_broadcast等函数不会修改条件变量的值。也就是说,当线程在进出条件变量的等待队列的时候是不会去唤醒等待队列中的其他线程的。当pthread_cond_wait函数成功返回时,互斥锁mutex将再次被锁上,这是pthread_cond_wait函数内部做的事情,就是为了防止在唤醒某个线程的时候和其他线程进出等待队列发生冲突。如果有一个线程正在进入等待队列,这时想要唤醒某个线程时就需要加锁,就会加锁失败,要等正在进入等待队列的线程彻底进去之后解锁,然后才能加锁去唤醒想要唤醒的线程,然后再加锁,然后出等待队列的之后在进行解锁。

注意:
线程被唤醒,pthread_cond_wait函数返回时,解除阻塞并重新申请获取互斥锁。

3.pthread_cond_broadcast()唤醒全部在等待条件变量的线程

在这里插入图片描述

参数解释:

参数cond:条件变量

4.pthread_cond_signal()唤醒一个在等待条件变量的线程(随机唤醒一个)

在这里插入图片描述

参数解释:

参数cond:条件变量

5.pthread_cond_destroy()销毁条件变量

在这里插入图片描述

参数解释:

参数cond:条件变量

三、条件变量的使用

【例】有两个线程A和B在等待队列中,给一个数组buff,当从键盘上向buff中写入数据之后,就随机唤醒一个线程去读取buff中的内容并输出,当从键盘上向buff中写入"end"的时候,唤醒所有正在等待的线程,让所有线程退出。

上例中,条件变量就是用户从键盘输入的数据,线程A和线程B根据条件变量的情况被唤醒。

代码如下 :

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>
#include<string.h>
#include<semaphore.h>pthread_cond_t cond;
pthread_mutex_t mutex;char buff[128]={0};void* fun_a(void* arg)
{while(1){//在线程A进入等待队列之前加锁,如果加锁成功,线程A进入等待队列,这时别的线程不可以进入等待队列pthread_mutex_lock(&mutex);//线程A进入等待队列中,线程B被阻塞,解锁,线程A被唤醒,加锁pthread_cond_wait(&cond,&mutex);//在线程A从等待队列出来之后,解锁,这时别的线程就可以进入等待队列pthread_mutex_unlock(&mutex);if(strncmp(buff,"end",3)==0)        {break;}else{printf("线程A输出:%s",buff);}}printf("线程A结束\n");
}void* fun_b(void* arg)
{while(1){//在线程B进入等待队列之前加锁,如果加锁成功,线程B进入等待队列,这时别的线程不可以进入等待队列pthread_mutex_lock(&mutex);//线程B进入等待队列中,线程B被阻塞,解锁,线程B被唤醒,加锁pthread_cond_wait(&cond,&mutex);//在线程B从等待队列出来之后,解锁,这时别的线程就可以进入等待队列pthread_mutex_unlock(&mutex);if(strncmp(buff,"end",3)==0){break;}else{printf("线程B输出:%s",buff);}}printf("线程B结束\n");
}int main()
{pthread_mutex_init(&mutex,NULL);pthread_cond_init(&cond,NULL);pthread_t id1,id2;pthread_create(&id1,NULL,fun_a,NULL);pthread_create(&id2,NULL,fun_b,NULL);while(1){fgets(buff,128,stdin);if(strncmp(buff,"end",3)==0){//唤醒所有pthread_cond_broadcast(&cond);break;}else{//随机唤醒一个pthread_cond_signal(&cond);}}pthread_join(id1,NULL);pthread_join(id2,NULL);pthread_mutex_destroy(&mutex);pthread_cond_destroy(&cond);exit(0);
}

运行结果:

在这里插入图片描述

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

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

相关文章

juc概述和Lock接口

目录 一、什么是JUC 1、JUC概述 2、进程与线程 3、线程的状态 4、wait/sleep 的区别 5、并发与并行 6、管程 7、用户线程和守护线程 二、Lock接口 1、Synchronized 使用synchronized实现售票案例 使用synchronized实现增减变量操作 2、什么是 Lock 买票例子使用lo…

Android基础——英文复习资料

一.填空题 1.An Android project must be bulit before it is run&#xff0c;compiling the java source code(.java flises)into Java bytetcode(.class files)and the into .dex files 2.In Android an activity stores the code for a screen of an app&#xff0c; …

PostMan 测试项目是否支持跨域

使用PostMan可以方便快速的进行跨域测试。 只需要在请求头中手动添加一个Origin的标头&#xff0c;声明需要跨域跨到的域&#xff08;IP&#xff1a;端口&#xff09;就行&#xff0c;其余参数PostMan会自动生成。添加此标头后&#xff0c;请求会被做为一条跨域的请求来进行处…

【快速解决方案】浏览器的安全策略不允许通过 file:// 协议直接加载外部文件(最省事的方法)

目录 问题摘要 解决办法 检验结果 问题摘要 Failed to load resource: net::ERR_FILE_NOT_FOUND&#x1f308; Cute Code Editor &#x1f308;.html:162 Fetch API cannot load file:///D:/%E6%A1%8C%E9%9D%A2/%E4%B8%83%E5%A4%95%E5%BF%AB%E4%B9%90/index.txt. URL scheme …

网银快捷支付接口怎么申请?

快速支付是一种方便的支付方式&#xff0c;允许用户在不重复输入卡号、密码等详细信息的情况下&#xff0c;使用预绑定的银行卡或支付账户进行快速支付。 在快速支付中&#xff0c;用户可以选择在商家网站、移动应用或支付平台上使用快速支付选项&#xff0c;并选择绑定的银行…

数据结构之——(手撕)顺序表

本章会介绍的知识点如下图&#xff1a; 1&#xff1a; 顺序表的概念&#xff1a;顺序表是用一段物理地址连续的存储单元依次存储数据的线性结构&#xff0c;通常我们使用数组来表示&#xff0c;对数组进行增删查改。 顺序表的结构&#xff1a;逻辑结构与物理结构都是内存中一块…

《vue3实战》在created生命周期中运用slice()方法结合element plus组件实现电影评价系统的分页

目录 前言 电影评价系统的分页是什么&#xff1f;它具体的作用体现在哪些方面&#xff1f; 一、slice的含义、语法和作用以及created的作用 slice是什么&#xff1f;slice有什么语法&#xff1f;slice的作用体现在哪些方面&#xff1f; created生命周期的作用&#xff1a;…

【C语言学习】指针变量

一、运算符& 1.&运算符可以获得变量的地址&#xff0c;它的操作数必须是变量 int i; printf("%x",&i);2.地址的大小是否与int相同取决于编译器 int i; printf("%p",&i);//%p以32进制输出i的地址二、指针变量 指针变量是保存地址的变量…

precision指标的average参数

同样适用于recall、F1 分类任务种类 先说一下分类任务分几种&#xff0c;分类任务主要分为二分类、多分类和多标签这三种。 现在假设我们有一个样本&#xff0c;叫s 二分类是最常见的&#xff0c;将s分给A或B这两类。 多分类是将s分给A或B或C或更多的类别。 多标签是有A、B、…

VSCode如何为远程安装预设(固定)扩展

背景 在使用VSCode进行远程开发时&#xff08;python开发之远程开发工具选择_CodingInCV的博客-CSDN博客&#xff09;&#xff0c;特别是远程的机器经常变化时&#xff08;如机器来源于动态分配&#xff09;&#xff0c;每次连接新的远程时&#xff0c;都不得不手动安装一些开…

【网络基础实战之路】VLAN技术在两个网段中的实际应用详解

系列文章传送门&#xff1a; 【网络基础实战之路】设计网络划分的实战详解 【网络基础实战之路】一文弄懂TCP的三次握手与四次断开 【网络基础实战之路】基于MGRE多点协议的实战详解 【网络基础实战之路】基于OSPF协议建立两个MGRE网络的实验详解 【网络基础实战之路】基于…

laravel aws s3

由于公司有境外项目&#xff0c;服务器、文件存储都是用的亚马逊&#xff0c;真真地是没有用过&#xff0c;在此记录一下自己的s3研究结果 Laravel - aws - s3 第一步创建用户&#xff0c;生成秘钥&#xff1a; 第二步创建存储桶&#xff1a; 1、创建存储桶时&#xff0c;以下…

html动态爱心代码【一】(附源码)

前言 七夕马上就要到了&#xff0c;为了帮助大家高效表白&#xff0c;下面再给大家带来了实用的HTML浪漫表白代码(附源码)背景音乐&#xff0c;可用于520&#xff0c;情人节&#xff0c;生日&#xff0c;表白等场景&#xff0c;可直接使用。 效果演示 文案修改 var loverNam…

对于个人来说,ChatGPT有什么用,缺点有哪些?

ChatGPT聊天机器人风靡全球&#xff0c;但也有一些人它认为模糊了原创性的界限&#xff0c;扼杀了创造力&#xff0c;还有些人害怕被机器人取代&#xff0c;由此失去生计和职业发展前景。 但更多的人更愿意积极拥抱ChatGPT&#xff0c;除了内容本身&#xff0c;最主要的是相比…

Power apps:做个简单的扫码应用

Power apps的扫码应用只能客户端使用 一、创建一个窗口"扫码APP”,插入媒体工具“条形码读卡器” 二、如果需要在扫码时做一个动作&#xff0c;可以设置它的属性&#xff0c;比如跳转窗口之类的 三、添加一个文本标签&#xff0c;实现在扫码后标签显示条形码&#xff08…

《Go 语言第一课》课程学习笔记(十)

复合数据类型 同构复合类型&#xff1a;从定长数组到变长切片 由多个同构类型&#xff08;相同类型&#xff09;或异构类型&#xff08;不同类型&#xff09;的元素的值组合而成&#xff0c;这类数据类型在 Go 语言中被称为复合类型。 数组有哪些基本特性&#xff1f; Go 语…

C语言和JavaScript中的默认排序行为对比

前言 今天在js里使用sort时遇见了一个不理解的现象 即使用sort默认排序后 9 从排序前的第一位被排到了最后一位.一开始我对js sort的理解和c一样&#xff0c;然后通过查阅后发现并不是这样. 正文 排序是一项常见而重要的操作。不同的编程语言提供了不同的排序函数&#xf…

【Unity3D】程序纹理简单应用

1 几何纹理应用 本文所有案例的完整资源详见→Unity3D程序纹理简单应用。 1.1 边框 1&#xff09;边框子图 Border.shadersubgraph 说明&#xff1a;Any 节点用于判断输入向量中是否存在一个分量非零&#xff0c;Branch 节点根据输入的真假走不同的分支&#xff0c;详见→Shad…

威班8月份PMP模拟考试实录(附大D老师考前寄语)

威班8月份模拟考试于2023年8月12日在深圳市福田区兴华大厦成功举办&#xff0c;这次考试依旧是通过线上线下同步的方式&#xff0c;在深圳周边的学员直接到达现场做卷考试&#xff0c;全国各地不能到达现场的其他学员已提前收到考试所需要的文件&#xff0c;与现场学员同时参加…

python解析小说

前言 在信息爆炸的时代&#xff0c;网络上充斥着大量的小说资源&#xff0c;让人们能够随时随地尽享阅读的乐趣。然而&#xff0c;有些小说网站要求用户付费才能获取完整的内容&#xff0c;这给许多人带来了困扰&#xff0c;尤其是像我这类对金钱概念模糊的人。不过&#xff0…