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

**与条件变量相关的api:

创建,销毁,触发,广播,等待
条件变量是线程另一可用的同步机制。条件变量给多个线程提供了一个汇合的场所。条件变量与互斥变量一起使用时,允许线程以无竞争的方式等待特定的条件发生。
条件本身是由互斥量保护的。线程在改变条件状态前必须首先锁住互斥量,其他线程在获得互斥量之前不会察觉到这种改变,因为必须锁定互斥量以后才能计算条件。
1、创建,销毁

//条件变量使用之前必须初始化,pthread_cond_init。
//条件变量的销毁:pthread_cond_destroy.
#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);

除非需要创建一个非默认属性的条件变量,否则pthread_cond_init函数attr参数可用设置为NULL。
2、等待

#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等待条件变为真。如果在给定的时间内条件不能满足,那么会生成一个代表一个出错码的返回量。传递给 pthread_cond_wait的互斥量对条件进行保护,调用者把锁住的互斥量传给函数。函数把调用线程放到等待条件的线程列表上,然后对互斥量解锁,这两个操作都是原子操作。这样就关闭了条件检查和线程进入休眠状态等待条件改变这两个操作之间的时间通道,这样线程就不会错过条件的任何变化。pthread_cond_wait返回时,互斥量再次被锁住。
pthread_cond_timedwait函数的工作方式与pthread_cond_wait函数类似,只是多了timeou。timeout指定了等待的时间,它是通过timespec结构指定。
3、触发

#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函数将唤醒等待该条件的所有进程。

*注:要在改变条件状态之后再给线程发信号。

4、例:
线程 1 等待,线程 2 先执行,当 g_data == 3 时,唤醒线程 1 执行

#include <stdio.h>
#include <pthread.h>int g_data = 0;pthread_mutex_t mutex;
pthread_cond_t cond;void *func1(void *arg)
{printf("t1: %ld thread is create!\n",(unsigned long)pthread_self());printf("t1: param is %d \n",*((int *)arg));while(1){pthread_cond_wait(&cond,&mutex);//等待条件变量if(g_data == 3){printf("-----------t1 run !----------");}printf("t1: %d\n",g_data++);sleep(1);g_data = 0;}}void *func2(void *arg)
{printf("t2: %ld thread is create!\n",(unsigned long)pthread_self());printf("t2: param is %d \n",*((int *)arg));while(1){printf("t2: %d\n",g_data);pthread_mutex_lock(&mutex);g_data++;if(g_data == 3){pthread_cond_signal(&cond);//触发条件变量}sleep(1);}
}int main()
{int ret;int param = 100;pthread_t t1;pthread_t t2;pthread_mutex_t init(&mutex,NULL);pthread_cond_init(&cond,NULL);//初始化条件变量int *pret = NULL;//创建线程ret = pthread_create(&t1,NULL,func1,(void *)&param);//调用func1函数if(ret == 0){
//		printf("main: create t1 success! \n");}ret = pthread_create(&t2,NULL,func1,(void *)&param);//调用func1函数if(ret == 0){
//		printf("main: create t2 success! \n");}//	printf("main: %ld\n",(unsigned long)pthread_self());//等待pthread_join(t1,(void **)&pret);pthread_join(t2,(void **)&pret);pthread_mutex_destroy (&mutex);pthread_cond_destroy(&cond);//销毁条件变量return 0;
}

运行结构:

t2:0
t2:1
t2:2
-----------t1 run !----------
t1:3
t2:0
t2:1
t2:2
-----------t1 run !----------
t1:3

5、测试
在线程 1 添加测试代码:

void *func1(void *arg)
{printf("t1: %ld thread is create!\n",(unsigned long)pthread_self());printf("t1: param is %d \n",*((int *)arg));static int cnt = 0;//测试while(1){pthread_cond_wait(&cond,&mutex);//等待条件变量if(g_data == 3){printf("-----------t1 run !----------");}printf("t1: %d\n",g_data++);sleep(1);g_data = 0;if(cnt++ == 10){		//测试10次exit(1);}}}

把要测试的文件编译为可执行文件:
gcc 文件 -lpthread -o 名文件:编译生成 名文件 可执行文件
再编写测试文件

int main(int argc,int **argv)
{int time=atoi(argv[1]);int i=0;for(i=0;i<time;i++){system("./名文件");}return 0;
}

编译测试文件,生成a.out 可执行文件文件
./a.out 5 >> test.ret.txt:运行 5 次 名文件 输出结果追加入test.ret.txt文档中

6、静态初始化:

之前的互斥锁和条件都使用的动态初始化;
静态初始化需要用到宏。

pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond=PTHREAD_COND_INITIALIZER;

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

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

相关文章

C语言数据结构之排序整合与比较(冒泡,选择,插入,希尔,堆排序,快排及改良,归并排序,计数排序)

前言&#xff1a;排序作为数据结构中的一个重要模块&#xff0c;重要性不言而寓&#xff0c;我们的讲法为下理论掌握大致的算法结构&#xff0c;再上代码及代码讲解&#xff0c;助你一臂之力。 一&#xff0c;冒泡 冒泡排序应该是大家学习以来第一个认识的排序方法&#xff0…

【小沐学前端】Node.js实现UDP和Protobuf 通信(protobuf.js)

文章目录 1、简介1.1 node1.2 Protobuf 2、下载和安装2.1 node2.2 Protobuf 3、node 代码示例3.1 HTTP3.2 UDP单播3.4 UDP广播 4、Protobuf 代码示例4.1 例子:awesome.proto 结语 1、简介 1.1 node Node.js 是一个开源的、跨平台的 JavaScript 运行时环境。 Node.js 是一个开源…

案例突破——再探策略模式

再探设计模式 一、背景介绍二、 思路方案三、过程1. 策略模式基本概念2. 策略模式类图3. 策略模式基本代码策略类抽象策略类Context类客户端 4. 策略模式还可以进行优化的地方5. 对策略模式的优化&#xff08;配置文件反射&#xff09; 四、总结五、升华 一、背景介绍 在做项目…

FPGA设计时序约束二、输入延时与输出延时

目录 一、背景 二、set_input_delay 2.1 set_input_delay含义 2.2 set_input_delay参数说明 2.3 使用样例 三、set_output_delay 3.1 set_output_delay含义 3.2 set_output_delay参数说明 3.3 使用样例 四、样例工程 4.1 工程代码 4.2 时序报告 五、参考资料 一、…

敏感性分析一览

敏感性分析 SobolMorrisFourier Amplitude Sensitivity Test (FAST)Random Balance Designs - Fourier Amplitude Sensitivity Test (RBD-FAST)Delta Moment-Independent MeasureDerivative-based Global Sensitivity Measure (DGSM)Fractional Factorial Sensitivity Analysis…

生产者、消费者问题

线程六个状态&#xff1a; public enum State {/*** 新生*/NEW,/*** 运行*/RUNNABLE,/***阻塞*/BLOCKED,/*** 等待*/WAITING,/*** 超时等待*/TIMED_WAITING,/**死亡**/TERMINATED;} synchronized和lock的区别 1、synchronized是关键字&#xff0c;lock是类 2、synchronized全自…

电压提前/滞后电路 —— 电赛综测备赛

电容可以让交流波形提前或滞后&#xff0c;不过很多人不知道用法 电压滞后电路 我们从中间输出给示波器 波形&#xff08;红色&#xff09; 电容越大电阻越大&#xff0c;波形越滞后 电压提前电路 波形&#xff08;红色&#xff09;提前 电容越小电阻越小&#xff0c;波形…

【Linux】——基操指令(二)

个人主页 代码仓库 C语言专栏 初阶数据结构专栏 Linux专栏 LeetCode刷题 算法专栏 目录 前言 man指令 cp 指令 mv指令 echo指令 cat指令 more指令 less指令 head和tail指令 head指令 tail指令 前言 上篇文章给大家讲解了Linux环境下的一点基操指令&#xf…

AVL树的模拟实现(c++)

目录 搜索二叉树对于搜索查询来说是非常快的&#xff0c;但是它有着致命的缺陷&#xff0c;如果插入的数据是有序的&#xff0c;那么它的结构就会退化成单链表&#xff0c;这对于搜索查询来说是非常不利的&#xff0c;因此为了解决搜索树的缺陷&#xff0c;弥补它的不足&#x…

select完成服务器并发

服务器 #include <myhead.h>#define PORT 4399 //端口号 #define IP "192.168.0.191"//IP地址//键盘输入事件 int keybord_events(fd_set readfds); //客户端交互事件 int cliRcvSnd_events(int , struct sockaddr_in*, fd_set *, int *); //客户端连接事件 …

error:03000086:digital envelope routines::initialization error

vue前端项目命令框输入npm run serve报error:03000086:digital envelope routines::initialization error错误 原因&#xff1a;node版本过高 解决办法&#xff1a; 在命令行输入命令修改环境变量&#xff1a;$env:NODE_OPTIONS"--openssl-legacy-provider" 然后再…

【Spring Cloud】深入理解 Eureka 注册中心的原理、服务的注册与发现

文章目录 前言一、微服务调用出现的问题1.1 服务消费者如何获取服务提供者的地址信息&#xff1f;1.2 如果有多个服务提供者&#xff0c;消费者该如何选择&#xff1f;1.3 消费者如何得知服务提供者的健康状态&#xff1f; 二、什么是 Eureka2.1 Eureka 的核心概念2.2 Eureka 的…

【论文极速读】Prompt Tuning——一种高效的LLM模型下游任务适配方式

【论文极速读】Prompt Tuning——一种高效的LLM模型下游任务适配方式 FesianXu 20230928 at Baidu Search Team 前言 Prompt Tuning是一种PEFT方法&#xff08;Parameter-Efficient FineTune&#xff09;&#xff0c;旨在以高效的方式对LLM模型进行下游任务适配&#xff0c;本…

vue wangEditor富文本编辑器 默认显示与自定义工具栏配置

1.vue 显示wangEditor富文本编辑器 <template><div style"border: 1px solid #ccc;"><Toolbar style"border-bottom: 1px solid #ccc" :editor"editor" :defaultConfig"toolbarConfig" :mode"mode"/><…

哈希表hash_table

一个人为什么要努力&#xff1f; 我见过最好的答案就是&#xff1a;因为我喜欢的东西都很贵&#xff0c;我想去的地方都很远&#xff0c;我爱的人超完美。文章目录 哈希表的引出unordered系列的关联式容器 底层结构哈希的概念 开放寻址法拉链法&#xff08;哈希桶&#xff09;拉…

毅速课堂:3D打印随形水路设计应注意什么?

随形水路是一种基于3D打印技术的新型模具冷却水路&#xff0c;能有效提高冷却效率、缩短冷却周期、提升产品良率、提高生产效率、 与传统的水路设计相比&#xff0c;随形水路更加贴合模具型腔表面&#xff0c;能够更加均匀地分配冷却水&#xff0c;使模具各部分的冷却效果得到有…

buuctf-[WUSTCTF2020]CV Maker

打开环境 随便登录注册一下 进入到了profile.php 其他没有什么页面&#xff0c;只能更换头像上传文件&#xff0c;所以猜测是文件上传漏洞 上传一句话木马看看 <?php eval($_POST[a]);?>回显 搜索一下 添加文件头GIF89a。上传php文件 查看页面源代码&#xff0c;看…

[红明谷CTF 2021]write_shell %09绕过过滤空格 ``执行

目录 1.正常短标签 2.短标签配合内联执行 看看代码 <?php error_reporting(0); highlight_file(__FILE__); function check($input){if(preg_match("/| |_|php|;|~|\\^|\\|eval|{|}/i",$input)){ 过滤了 木马类型的东西// if(preg_match("/| |_||php/&quo…

Springboot中使用拦截器、过滤器、监听器

一、Servlet、Filter&#xff08;过滤器&#xff09;、 Listener&#xff08;监听器&#xff09;、Interceptor&#xff08;拦截器&#xff09; Javaweb三大组件&#xff1a;servlet、Filter&#xff08;过滤器&#xff09;、 Listener&#xff08;监听器&#xff09; Spring…

【力扣周赛】第 364 场周赛⭐(前后缀分解+单调栈DFS技巧)

文章目录 竞赛链接Q1&#xff1a;2864. 最大二进制奇数&#xff08;贪心&#xff09;写法1——手动模拟&#xff08;代码长&#xff0c;运行快&#xff09;写法2——API&#xff08;代码短&#xff0c;运行慢&#xff09; Q2&#xff1a;2865. 美丽塔 I竞赛时代码——枚举山顶 …