Linux--线程-条件控制实现线程的同步

1.条件变量

条件变量是线程另一可用的同步机制。条件变量给多个线程提供了一个会合的场所。条件变量与互斥量一起使用时,允许线程以无竞争的方式等待特定的条件发生。

条件本身是由互斥量保护的。线程在改变条件状态前必须首先锁住互斥量,其他线程在获得互斥量之前不会察觉到这种改变,因为必须锁定互斥量以后才能计算条件。

条件变量使用之前必须首先初始化,pthread_cond_t数据类型代表的条件变量可以用两种方式进行初始化,可以把常量PTHREAD_COND_INITIALIZER赋给静态分配的条件变量,但是如果条件变量是动态分配的,可以使用pthread_cond_destroy函数对条件变量进行去除初始化(deinitialize)。

2.创建及销毁条件变量

函数原型:

#include <pthread.h>
int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr);
int pthread_cond_destroy(pthread_cond_t cond);
// 返回:若成功返回0,否则返回错误编号

参数说明:

pthread_cond_init

  • cond:指向要初始化的条件变量的指针。
  • attr:指向条件变量属性的指针,可以为NULL。如果为NULL,则使用默认属性。

返回值:

  • 如果成功,返回0;否则返回错误码。

3.等待

函数原型:

#include <pthread.h>
int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);
int pthread_cond_timedwait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex, cond struct timespec *restrict timeout);
// 返回:若成功返回0,否则返回错误编号
 

参数说明:

pthread_cond_wait

  • cond:指向要等待的条件变量的指针。
  • mutex:指向互斥锁的指针,用于保护条件变量。

返回值:

  • 如果成功,返回0;否则返回错误码。

pthread_cond_timedwait

 

参数说明:

  • cond:指向要等待的条件变量的指针。
  • mutex:指向互斥锁的指针,用于保护条件变量。
  • abstime:指向一个timespec结构体的指针,表示等待的最长时间。如果设置为NULL,则表示无限等待。

返回值:

  • 如果成功,返回0;否则返回错误码。

pthread_cond_wait等待条件变为真。如果在给定的时间内条件不能满足,那么会生成一个代表一个出错码的返回变量。传递给pthread_cond_wait的互斥量对条件进行保护,调用者把锁住的互斥量传给函数。函数把调用线程放到等待条件的线程列表上,然后对互斥量解锁,这两个操作都是原子操作。这样就关闭了条件检查和线程进入休眠状态等待条件改变这两个操作之间的时间通道,这样线程就不会错过条件的任何变化。

pthread_cond_wait返回时,互斥量再次被锁住。

pthread_cond_timedwait函数的工作方式与pthread_cond_wait函数类似,只是多了一个timeout。timeout指定了等待的时间,它是通过timespec结构指定。
 

4.触发
函数原型:

#include <pthread.h>
int pthread_cond_signal(pthread_cond_t cond);
int pthread_cond_broadcast(pthread_cond_t cond);
// 返回:若成功返回0,否则返回错误编号

这两个函数可以用于通知线程条件已经满足。
pthread_cond_signal函数将唤醒等待该条件的某个线程,而pthread_cond_broadcast函数将唤醒等待该条件的所有进程。
注意一定要在改变条件状态以后再给线程发信号。

代码:

#include<stdio.h>
#include<pthread.h>
#include <unistd.h>
#include<stdlib.h>
int data = 0;//定义一个全局变量data 
pthread_mutex_t mutex; //还可以直接定义和初始化好 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER
pthread_cond_t cond; //pthread_cond_t cond = PTHREAD_COND_INITIALIZER
void *func1(void *arg)
{
        static int cnt = 0;
        while(1){
                pthread_cond_wait(&cond,&mutex);//收到信号
                printf("===========t1 tun============\n");

                printf("t1线程拿到data:%d\n",data);
                data = 0;
                sleep(1);

                if(cnt++ == 3){
                        printf("结束!\n");
                        exit(1);//达到条件,结束整个程序

                }
        }

}
void *func2(void *arg)
{

        while(1){
                printf("线程t2拿到 data = %d\n",data);
                pthread_mutex_lock(&mutex);//先拿到互斥锁,先运行
                data++;
                if(data == 3){
                   pthread_cond_signal(&cond);//达到条件,向线程t1发送信号
                }
                pthread_mutex_unlock(&mutex);
                sleep(1);
        }
}
int main()
{
        int ret;
        int param = 100;
        pthread_t t1;
        pthread_t t2;

        pthread_mutex_init(&mutex,NULL);
        pthread_cond_init(&cond,NULL);//动态初始化条件变量

        ret = pthread_create(&t1,NULL,func1,(void *)&param);//创建线程t1
        if(ret == 0){
                //      printf("main:创建线程t1成功!\n");
        }

        ret = pthread_create(&t2,NULL,func2,(void *)&param);//创建线程t2
        if(ret == 0){
                //      printf("main:创建线程t2成功!\n");
        }

        pthread_join(t1,NULL);
        pthread_join(t2,NULL);
        pthread_mutex_destroy(&mutex);
        pthread_cond_destroy(&cond);
        return 0;
}

结果:

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

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

相关文章

大航海时代Ⅳ 威力加强版套装 HD Version (WinMac)中文免安装版

《大航海时代》系列的人气SRPG《大航海时代IV》以HD的新面貌再次登场&#xff01;本作品以16世纪的欧洲“大航海时代”为舞台&#xff0c;玩家将以探险家、商人、军人等不同身份与全世界形形色色的人们一起上演出跌宕起伏的海洋冒险。游戏中玩家的目的是在不同的海域中掌握霸权…

新技术前沿-2023-应用GPT提问模板写技术文章

参考一份万能的GPT提问模版&#xff01;直接套用&#xff01; 参考用GPT写技术文章是真爽&#xff01; 参考码住这篇 8200 字 ChatGPT 实战指南&#xff01;&#xff01; 1 GPT提问模板 想让GPT回答的内容符合我们所希望的&#xff0c;最最重要的一点就在于我们如何提问。提问…

【C++】一篇文章搞懂auto关键字及其相关用法!

&#x1f490; &#x1f338; &#x1f337; &#x1f340; &#x1f339; &#x1f33b; &#x1f33a; &#x1f341; &#x1f343; &#x1f342; &#x1f33f; &#x1f344;&#x1f35d; &#x1f35b; &#x1f364; &#x1f4c3;个人主页 &#xff1a;阿然成长日记 …

【Mybatis小白从0到90%精讲】11:Mybatis批量插入 batchInsert

文章目录 前言foreach批量插入前言 在实际开发中,我们经常需要批量插入大量数据到数据库中,而MyBatis也提供了批量插入的支持,可以大大提高插入效率。 今天要分享的是 工作中常用的在Mapper中使用foreach标签批量插入数据的方式,比在Java代码中循环调用Mapper的单条插入性…

SpringBoot整合EasyExcel

springboot整合easyExcel的全流程&#xff0c;跟着做就能出来。对项目没有侵入要求。0侵入&#xff0c;可插拔 依赖 <!--操作Excel依赖--><dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>…

微信小程序 uCharts的使用方法

一、背景 微信小程序项目需要渲染一个柱状图&#xff0c;使用uCharts组件完成 uCharts官网指引&#x1f449;&#xff1a;uCharts官网 - 秋云uCharts跨平台图表库 二、实现效果 三、具体使用 进入官网查看指南&#xff0c;有两种方式进行使用&#xff1a;分别是原生方式与组…

康耐视深度学习ViDi-Tool菜单介绍

Train 训练该工具中所有标注的图像 Process 处理该工具中所有的图像 Abort 中止当前训练或处理任务 Rename 更改当前工具的名称 Clone 克隆当前所选工具 Import导出当前所选工具 Export导入相对应的工具 Edit Models编辑工具中的模型 Update Parameters更新当前工具参数 工具菜…

专访虚拟人科技:如何利用 3DCAT 实时云渲染打造元宇宙空间

自古以来&#xff0c;人们对理想世界的探索从未停止&#xff0c;而最近元宇宙的热潮加速了这一步伐&#xff0c;带来了许多新的应用。作为元宇宙的关键入口&#xff0c;虚拟现实&#xff08;VR&#xff09;将成为连接虚拟和现实的桥梁。苹果发布的VISION PRO头戴设备将人们对VR…

C#使用随机数模拟英雄联盟S13瑞士轮比赛

瑞士轮赛制的由来 瑞士制&#xff1a;又称积分循环制&#xff0c;最早出现于1895年在瑞士苏黎世举办的国际象棋比赛中&#xff0c;故而得名。其基本原则是避免种子选手一开始就交锋、拼掉&#xff0c;是比较科学合理、用得最多的一种赛制&#xff1b;英语名称为Swiss System。…

多态 多继承的虚表深度剖析 (3)

&#x1f4af; 博客内容&#xff1a;多态 &#x1f600; 作  者&#xff1a;陈大大陈 &#x1f680; 个人简介&#xff1a;一个正在努力学技术的准C后端工程师&#xff0c;专注基础和实战分享 &#xff0c;欢迎私信&#xff01; &#x1f496; 欢迎大家&#xff1a;这里是CSD…

【ES专题】ElasticSearch集群架构剖析

目录 前言阅读对象阅读导航前置知识笔记正文一、ES集群架构1.1 为什么要使用ES集群架构1.2 ES集群核心概念1.2.1 节点1.2.1.1 Master Node主节点的功能1.2.1.2 Data Node数据节点的功能1.2.1.3 Master Node主节点选举流程 1.2.2 分片1.3 搭建三节点ES集群1.3.1 ES集群搭建步骤1…

2、k8s 集群安装

1、kubeadm kubeadm 是官方社区推出的一个用于快速部署 kubernetes 集群的工具。 这个工具能通过两条指令完成一个 kubernetes 集群的部署&#xff1a; # 创建一个 Master 节点 $ kubeadm init # 将一个 Node 节点加入到当前集群中 $ kubeadm join <Master 节点的 IP 和端口…

mipi DPHY学习记录

DPHY的内容很多,而且细节很多,我会一点一点的进行补充记录,今天要记录的是cdphy的LP-MODE数据传输的过程。 1:HS 和LP mode lane status 和 lane上的电压 HS mode时,差分线上的电压摆幅为200mv,LP mode时,差分线上的电压为1.2v 2:HS mode data Transmission start 在…

北大软微2024推免拟录取名单及分析

拟录取名单 直博生 硕士生 分析 北大软微在2023年的推免中共录取直博生17人&#xff0c;硕士生205人&#xff0c;其中硕士生全为专硕电子信息 当然&#xff0c;从录取结果咱们可以看出来&#xff0c;除了985和强势211&#xff0c;中国地质&#xff08;北京&#xf…

STM32-高级定时器

以STM32F407为例。 高级定时器 高级定时器比通用定时器增加了可编程死区互补输出、重复计数器、带刹车&#xff08;断路&#xff09;功能&#xff0c;这些功能都是针对工业电机控制方面。 功能框图 16位向上、向下、向上/向下自动重装载计数器。 16位可编程预分频器&#xff0c…

时间序列预测模型实战案例(八)(Informer)BestPaper论文模型Informer代码实战讲解

论文地址->Informer论文地址PDF点击即可阅读 代码地址-> 论文官方代码地址点击即可跳转下载GIthub链接 本文介绍 本篇博客带大家看的是Informer模型进行时间序列预测的实战案例&#xff0c;它是在2019年被提出并在ICLR 2020上被评为Best Paper&#xff0c;可以说Inform…

JAVA应用中线程池设置多少合适?

目录 1、机器配置&#xff1a; 2、核心线程数 3、最大线程数多少合适&#xff1f; 4、理论基础 5、测试验证 一个线程跑满一个核心的利用率 6个线程 12 个线程&#xff1a;所有核的cpu利用率都跑满 有io操作 6、计算公式 7、决定最大线程数的流程&#xff1a; 1、机器…

HCIA数据通信——路由协议

数据通信——网络层&#xff08;OSPF基础特性&#xff09;_咕噜跳的博客-CSDN博客 数据通信——网络层&#xff08;RIP与BGP&#xff09;_咕噜跳的博客-CSDN博客 上述是之前写的理论知识部分&#xff0c;懒得在实验中再次提及了。这次做RIP协议以及OSPF协议。不过RIP协议不常用…

【Tricks】vscode winscp进行服务器容器连接(含修改初始密码)

1&#xff1a;获取docker的登陆信息 例如节点&#xff08;host&#xff09;、端口&#xff08;port&#xff09;、密码&#xff08;passwd&#xff09;等信息&#xff0c;这个自己找组内的前辈获取即可 2&#xff1a;配置config文件 找到vscode里面ssh处的config文件 人工找…

【unity3D】使用RawImage实现UI上的帧动画

&#x1f4a6;本专栏是我关于游戏开发的笔记 &#x1f236;本篇是一个简短的小知识点 使用RawImage实现帧动画 找一个帧动画连续的图片拖到工程中&#xff0c;将Texture Type改成Sprite&#xff08;2D和UI&#xff09;&#xff0c;点击apply应用上 在工程中新建一个RawImage,将…