pthread几个互斥锁和条件变量接口
2016-04-16 17:46
357 查看
pthread_cleanup_push/pthread_cleanup_pop:pthread_cleanup_push(pthread_mutex_unlock, (void *) &mut); //可以注册pthread_mutex_unlock,也可以注册自定义的函数pthread_mutex_lock(&mut);//do something。此过程中假如本线程做某些事时异常退出,或者被别的线程cancel,那么mut就永远得不到执行pthread_mutex_unlock(&mut);pthread_cleanup_pop(0);pthread_cond_wait(&cond, &mut):内部顺序执行pthread_mutex_unlock(&mut),pthread_cond_just_wait(&cond),pthread_mutex_lock(&mut),其中,前两个函数(unlock和just_wait)必须从语义上原子化。如果不原子化,会出现unlock之后别的线程获得mut,然后发送signal/broadcast,最后本线程调用just_wait。也就是说just_wait发生在signal/broadcast之前,所以本线程永远不会得到唤醒。对于同一个cond,必须用同一个mut来配合使用。使用示例如下:
此外,注意如果有多个线程在等待条件变量时,需要用while(flag!=true),在wait返回的时候再判断一次flag。原因是wait执行时可能存在下面的场景(signal/broadcast惊群,线程1和线程3同时收到信号):
pthread_mutex_lock(&mut);while(flag!=true) //如果flag不为true,我们调cond_wait把自己给阻塞了pthread_cond_wait(&cond,&mut); //前后必须要加互斥锁,而pthread_cond_signal前后则无所谓加不加互斥锁pthread_mutex_unlock(&mut);pthread_cond_wait()前后必须加互斥锁,是为了保证对条件flag的互斥访问,如果不加互斥锁,可能出现如下情况:
thread1: thread2:while(flag!=true) //flag==falseflag=true; //flag==truepthread_cond_wait(); //thread1已进入阻塞状态,但其实此时flag是为true的,即漏过了这个条件了..........另外,pthread_cond_wait(&cond,&mut)内部大致包含下面几个步骤:1、进入wait,处理条件变量,2、解锁mut;3、把自己给阻塞了;4、睡眠;5、睡眠;6、。。。7、收到别的线程通知(pthread_cond_signal/broadcast)可以醒了;8、醒来;9、尝试锁定mut,如果成功则函数返回;10、不成功的话阻塞并等待mut可用。以上步骤,可以由下图(来自pthread条件变量condition(配合mutex锁使用),经典,有图)描述:
线程1 线程31、收到别的线程通知(pthread_cond_signal/broadcast)可以醒了; 1、收到别的线程通知(pthread_cond_signal/broadcast)可以醒了;2、尝试加锁mut失败; 2、成功锁定mut;3、睡眠 3、置flag为false;4、睡眠 4、解锁mut;5、成功锁定mut;6、wait函数返回,线程醒来。线程1醒来后必须再判断flag,flag可能为false了,因为线程1加锁mut失败的时候flag被别的线程修改了。pthread_cond_signal():有两种用法,都可以:用法1: 用法2:pthread_mutex_lock(&mut); pthread_mutex_lock(&mut);atomic_i++; atomic_i++;pthread_cond_signal(&cond); pthread_mutex_unlock(&mut);pthread_mutex_unlock(&mut); pthread_cond_signal(&cond);两种用法各有优缺点:用法1在某些OS的实现中,可能会造成signal之后还没unlock,但是另一个收到cond的线程在cond_wait()中最后试图lock,lock失败,导致重新陷入内核态,直到本线程unlock,由此带来性能损失。用法2会出现unlock之后signal之前有别的低优先级线程抢占了mut,导致更高优先级的等待cond_wait的线程被低优先级线程抢占。用法1在Linux下不会有上面提到的缺点,因为在Linux中,cond_signal只会让线程从cond_wait队列移到mutex_lock队列。
相关文章推荐
- 青蛙的约会gcd
- android Mediaplayer各种属性和方法简单介绍
- Ubuntu下搭建tftp服务器最简单方法
- 每天一个linux命令(8):rm
- 线性表基本操作
- 2016.4.16
- Codeforces Gym 100543G Virus synthesis
- 线程通讯的几种方式
- 近100个linux常用命令大全
- java web 分页实现的补充
- 解析jsp的 tomcat 、resin
- 第七周学习进度条
- 每天一个linux命令(7):mv
- jqery和js如何判断checkbox是否选中
- C r and n(组合数)
- 高光谱ENVI4.7、5.0、5.1下载与打开使用
- OpenWRT校园网ipv6设置
- C r and n(组合数)
- siegen程计算机常用术语解析之依赖注入。
- listView优化以及内存泄露问题