当前位置: 首页 > news >正文

Linux线程——条件变量

什么是条件变量

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

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

条件变量使用之前必须首先初始化

静态初始化:pthread_cond_t cond = PTHREAD_COND_INITIALIZER可以把常量PTHREAD_COND_INITIALIZER赋给静态分配的条件变量。

动态初始化:pthread_cond_init(&cond,NULL);如果条件变量是动态分配的,可以使用pthread_cond_destroy函数对条件变量进行去除初始化(deinitialize)。
 

相关API

包含头文件

#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);
参数解读
*cond全局变量pthread_cond_t cond的地址(pthread_cond_init(&cond,NULL);)
attr除非需要创建一个非默认属性的条件变量,否则pthread_cont_init函数的attr参数可以设置为NULL(pthread_cond_destroy(&cond);)
返回值

若成功返回0,否则返回错误编号。

等待条件变量

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

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

pthread_cond_wait立即返回,pthread_cond_wait等待一段时间后返回。

函数原型
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);
参数解读
*cond全局变量pthread_cond_t cond的地址
*restrict mutex全局变量pthread_mutex_t mutex的地址
返回值

若成功返回0,否则返回错误编号。

触发条件变量

这两个函数可以用于通知线程条件已经满足。pthread_cond_signal函数将唤醒等待该条件的某个线程,而pthread_cond_broadcast函数将唤醒等待该条件的所有进程

函数原型
int pthread_cond_signal(pthread_cond_t *cond);
int pthread_cond_broadcast(pthread_cond_t *cond);
参数解读

*cond:全局变量pthread_cond_t cond的地址。

返回值

若成功返回0,否则返回错误编号。

代码示例

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

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>int data = 0;pthread_mutex_t mutex;
pthread_cond_t cond;//定义一个全局变量的条件变量
//pthread_cond_t cond = PTHREAD_COND_INITIALIZER//这也是初始化的一种并定义一个全局变量void *func1(void *arg)
{while(1){pthread_cond_wait(&cond,&mutex);//等待func2触发条件变量printf("over!!!!!!!!!!!!!!!!!!\n");data = 0;//将data置于0 则data不等3会重新进入func2sleep(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);//触发条件变量 func1等待接受后执行func1代码}pthread_mutex_unlock(&mutex);//解锁sleep(1);}
}int main()
{int ret;int num =999;pthread_t t1;pthread_t t2;pthread_mutex_init(&mutex,NULL);pthread_cond_init(&cond,NULL);//条件变量初始化ret = pthread_create(&t1,NULL,func1,(void *)&num);if(ret == 0){//printf("main:create thread success\n");}ret = pthread_create(&t2,NULL,func2,(void *)&num);if(ret == 0){//printf("main:create thread success\n");}pthread_join(t1,NULL);pthread_join(t2,NULL);	pthread_mutex_destroy(&mutex);pthread_cond_destroy(&cond);//销毁条件变量return 0;
}

由编译结果可知:data不等于3时fucn2会拿到互斥量并执行其中代码,当data等于3时触发条件变量并解锁,此时func1接受条件变量并将data重新置0,data等于0后func2就会重新进行。

相关文章:

  • 快速能访问服务器的文件
  • Web请求与响应
  • 修改blackd源码,实现 black + isort
  • 银行测试:第三方支付平台业务流,功能/性能/安全测试方法
  • 最新国内可用使用GPT4.0,GPT语音对话,Midjourney绘画,DALL-E3文生图
  • MySQL基本操作 DDL DML DQL三大操作介绍
  • vue打包内存问题解决办法<--- Last few GCs ---><--- JS stacktrace --->
  • linux驱动的学习 驱动开发初识
  • 命令执行 [SWPUCTF 2021 新生赛]babyrce
  • 服务器直接配置免密登录
  • 你想改win11系统中窗口、菜单等的字体? 微软不想让你改
  • 环境搭建及源码运行_java环境搭建_idea版本下载及安装
  • flutter自定义地图Marker完美展示图片
  • springboot(ssm电商应用系统 在线购物系统Java系统
  • Java 栈和队列的交互实现
  • 0基础学习移动端适配
  • CentOS 7 防火墙操作
  • create-react-app项目添加less配置
  • es6
  • gitlab-ci配置详解(一)
  • JavaScript中的对象个人分享
  • Java应用性能调优
  • JS变量作用域
  • k个最大的数及变种小结
  • LeetCode算法系列_0891_子序列宽度之和
  • mockjs让前端开发独立于后端
  • SpiderData 2019年2月23日 DApp数据排行榜
  • vue从创建到完整的饿了么(11)组件的使用(svg图标及watch的简单使用)
  • 从tcpdump抓包看TCP/IP协议
  • 分布式事物理论与实践
  • 工程优化暨babel升级小记
  • 基于Volley网络库实现加载多种网络图片(包括GIF动态图片、圆形图片、普通图片)...
  • 基于web的全景—— Pannellum小试
  • 开年巨制!千人千面回放技术让你“看到”Flutter用户侧问题
  • 浏览器缓存机制分析
  • 猫头鹰的深夜翻译:JDK9 NotNullOrElse方法
  • 详解NodeJs流之一
  • 用jquery写贪吃蛇
  • 用Node EJS写一个爬虫脚本每天定时给心爱的她发一封暖心邮件
  • 在Docker Swarm上部署Apache Storm:第1部分
  • 在Mac OS X上安装 Ruby运行环境
  • 400多位云计算专家和开发者,加入了同一个组织 ...
  • JavaScript 新语法详解:Class 的私有属性与私有方法 ...
  • 第二十章:异步和文件I/O.(二十三)
  • 关于Kubernetes Dashboard漏洞CVE-2018-18264的修复公告
  • #define用法
  • (¥1011)-(一千零一拾一元整)输出
  • (04)Hive的相关概念——order by 、sort by、distribute by 、cluster by
  • (day6) 319. 灯泡开关
  • (八)五种元启发算法(DBO、LO、SWO、COA、LSO、KOA、GRO)求解无人机路径规划MATLAB
  • (附源码)spring boot儿童教育管理系统 毕业设计 281442
  • (附源码)ssm学生管理系统 毕业设计 141543
  • (剑指Offer)面试题41:和为s的连续正数序列
  • (转)LINQ之路
  • .[backups@airmail.cc].faust勒索病毒的最新威胁:如何恢复您的数据?