文档章节

关于pthread_cond_signal与pthread_cond_broadcast的使用...

 天下杰论
发布于 2012/10/18 13:38
字数 939
阅读 2746
收藏 1
点赞 0
评论 0

       在code review中,我会发现很多人喜欢在pthread_mutex_lock()和pthread_mutex_unlock(()之间调用 pthread_cond_signal或者pthread_cond_broadcast函数,从逻辑上来说,这种使用方法是完全正确的。但是在多线程环境中,这种使用方法可能是低效的。posix1标准说,pthread_cond_signal与pthread_cond_broadcast无需考虑调用线程是否是mutex的拥有者,也就是说,可以在lock与unlock以外的区域调用。如果我们对调用行为不关心,那么请在lock区域之外调用吧。这里举个例子:
      
我们假设系统中有线程1和线程2,他们都想获取mutex后处理共享数据,再释放mutex。请看这种序列:
      
1)线程1获取mutex,在进行数据处理的时候,线程2也想获取mutex,但是此时被线程1所占用,线程2进入休眠,等待mutex被释放。
      
2)线程1做完数据处理后,调用pthread_cond_signal()唤醒等待队列中某个线程,在本例中也就是线程2。线程1在调用pthread_mutex_unlock()前,因为系统调度的原因,线程2获取使用CPU的权利,那么它就想要开始处理数据,但是在开始处理之前,mutex必须被获取,很遗憾,线程1正在使用mutex,所以线程2被迫再次进入休眠。
       
3)然后就是线程1执行pthread_mutex_unlock()后,线程2方能被再次唤醒。
       从这里看,使用的效率是比较低的,如果再多线程环境中,这种情况频繁发生的话,是一件比较痛苦的事情。所以觉得,如果程序不关心线程可预知的调度行为,那么最好在锁定区域以外调用他们。

对于
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime);
,一定要在mutex的锁定区域内使用。
如果要正确的使用pthread_mutex_lock与pthread_mutex_unlock,请参考
pthread_cleanup_push 和pthread_cleanup_pop宏,它能够在线程被cancel的时候正确的释放mutex!

        pthread_cond_wait()  用于阻塞当前线程,等待别的线程使用 pthread_cond_signal() pthread_cond_broadcast来唤醒它  pthread_cond_wait()   必须与pthread_mutex 配套使用。 pthread_cond_wait() 函数一进入wait状态就会自动release mutex。当其他线程通过 pthread_cond_signal() pthread_cond_broadcast ,把该线程唤醒,使 pthread_cond_wait()通过(返回)时,该线程又自动获得该 mutex
        pthread_cond_signal 函数的作用是发送一个信号给另外一个正在处于阻塞等待状态的线程,使其脱离阻塞状态,继续执行.如果没有线程处在阻塞等待状态,pthread_cond_signal也会成功返回。
        使用pthread_cond_signal一般不会有“惊群现象”产生,他最多只给一个线程发信号。假如有多个线程正在阻塞等待着这个条件变量的话,那么是根据各等待线程优先级的高低确定哪个线程接收到信号开始继续执行。如果各线程优先级相同,则根据等待时间的长短来确定哪个线程获得信号。但无论如何一个pthread_cond_signal调用最多发信一次。
        但是 pthread_cond_signal 在多处理器上可能同时唤醒多个线程,当你只能让一个线程处理某个任务时,其它被唤醒的线程就需要继续 wait,而且规范要求 pthread_cond_signal 至少唤醒一个pthread_cond_wait上的线程,其实有些实现为了简单在单处理器上也会唤醒多个线程. 
        另外,某些应用,如线程池, pthread_cond_broadcast 唤醒全部线程,但我们通常只需要一部分线程去做执行任务,所以其它的线程需要继续wait.
 
http://apps.hi.baidu.com/share/detail/19786281
 

本文转载自:

共有 人打赏支持
粉丝 53
博文 442
码字总数 23359
作品 0
沈阳
项目经理
【原创】手把手教你Linux下的多线程设计--Linux下多线程编程详解(四)

本文可任意转载,但必须注明作者和出处。 【原创】手把手教你Linux下的多线程设计(四) --Linux下多线程编程详解 原创作者:Frozen_socker(冰棍) E_mail:dlskyfly@163.com 线程同步 首先来...

gaoshouma
2007/07/11
0
0
转载的关于pthread_cond_wait的文章,写的比较详细

三、Glibc的实现 1、数据结构 / Data structure for conditional variable handling. Thestructure of the attribute type is not exposed on purpose. / typedef union { struct { int loc......

zhegaozhouji
2017/06/19
0
0
Condition Variables(条件变量)用法指南

int pthreadcondtimedwait(pthreadcondt *restrict cond, pthreadmutext restrict mutex,const struct timespec restrict abstime); int pthreadcondwait(pthreadcondt *restrict cond, pthr......

技术小美
2017/11/12
0
0
pthread_cond_signal和pthread_cond_wait简介

pthreadcondsignal函数的作用是发送一个信号给另外一个正在处于阻塞等待状态的线程,使其脱离阻塞状态,继续执行.如果没有线程处在阻塞等待状态,pthreadcondsignal也会成功返回。 但使用pthre...

天下杰论
2013/08/08
0
0
linux多线程学习(五)---条件变量

1. 相关函数 #include pthreadcondt cond = PTHREADCONDINITIALIZER; int pthreadcondinit(pthreadcondt cond, pthreadcondattrt condattr); int pthreadcondsignal(pthreadcondt *cond); i......

长平狐
2012/09/03
61
0
线程条件变量pthread_cond_t (Ubuntu 12.04)

1.初始化条件变量pthreadcondinit #include <pthread.h>int pthreadcondinit(pthreadcondt cv, const pthreadcondattrt cattr);返回值:函数成功返回0;任何其他返回值都表示错误 初始化一个......

B_ice
2016/07/24
1
0
Linux多线程编程详细解析----条件变量 pthread_cond_t

Linux操作系统下的多线程编程详细解析----条件变量 1.初始化条件变量pthreadcondinit #include int pthreadcondinit(pthreadcondt *cv, const pthreadcondattrt *cattr); 返回值:函数成功返...

长平狐
2013/01/06
43
0
Linux多线程编程详细解析----条件变量 pthread_cond_t

Linux操作系统下的多线程编程详细解析----条件变量 1.初始化条件变量pthreadcondinit #include int pthreadcondinit(pthreadcondt *cv, const pthreadcondattrt *cattr); 返回值:函数成功返...

晨曦之光
2012/03/02
3K
0
Linux多线程编程四(条件变量)

前一节中我们讲述了如何使用互斥锁来实现线程间数据的共享和通信,互斥锁一个明显的缺点是它只有两种状态:锁定和非锁定。而条件变量通过允许线程阻塞和等待另一个线程发送信号的方法弥补了互...

wannneg
2016/04/16
35
0
Linux平台上C语言实现异步队列的两种方法

Linux上目前有两种事件通知方式,一种是线程条件变量,一种是利用eventfd实现事件通知,下面介绍一下利用这两种方法实现异步队列的方法。 线程条件变量 相关函数介绍 pthreadcondinit:初始化...

frank21
2014/02/27
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

崛起于Springboot2.X之集成MongoDb使用mongoTemplate CRUD(27)

1、pom依赖 <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.7</version></dependency><dependency> <groupId>log4j</......

木九天
8分钟前
0
0
切分log日志

新建logback.xml放到resource里面 <?xml version="1.0" encoding="utf-8"?><configuration> <appender name="consoleLog" class="ch.qos.logback.core.ConsoleAppender"> <......

talen
13分钟前
0
0
spring @Resource 和 @Autowired 的使用区别

这两个 注解 @Resource 和 @Autowired , 常识都知道 @Resource 是 JAVAEE 自带的,@Autowired 是 spring 的自定义注解。 一般情况下, 使用 bean的时候, 这两个注解 随便使用一个即可。 但...

之渊
19分钟前
0
0
springboot集成elasticsearch客户端问题记录

1背景说明 服务端ES版本为5.5.2,springboot版本为1.5.6。 工程中添加如下依赖 2问题记录 2.1 NetworkPlugin类找不到 报错java.lang.ClassNotFoundException: org.elasticsearch.plugins.Net...

zjg23
20分钟前
1
0
快速构建ceph可视化监控系统

前言 ceph的可视化方案很多,本篇介绍的是比较简单的一种方式,并且对包都进行了二次封装,所以能够在极短的时间内构建出一个可视化的监控系统 本系统组件如下: ceph-jewel版本 ceph_expor...

万建宁
20分钟前
0
0
Java构造器使用注意

public class 父类A {int age = 10;protected void say() {System.out.println("父类A");}public 父类A() {override();}public void override() {Syst...

咸鱼AI
21分钟前
0
0
TensorFlow 线性分类

构造直线 z = 2 * x - 3 * y + 4 x0*w0+x1*w1+b=0 x1=-x0* w0/w1-b/w1 斜率 k= -w0/w1 截距 -b/w1 随机生成数据,加入一定的偏差,用直线将二维平面分为两部分 使用线性模型拟合参数 损失函数...

阿豪boy
24分钟前
0
0
翻译冒泡排序测试

翻译一个冒泡排序: var a = [1,3,2,4,6,5];var f = 0;var n = a.length ;for( var i =1; i<= n; i++) { for( var j = n-1 ; j >= i; j --) { if(a[j] < a[j+1]) { ......

钟元OSS
25分钟前
0
0
maven父、子级版本号同时修改

命令: mvn versions:set -DnewVersion=0.0.2-SNAPSHOT

沉默的懒猫
27分钟前
0
0
Spring boot中的异常处理之注解响应

Controller层 return patientRepository.findById(id) .orElseThrow(() -> new NotFoundException(String.format("Patient %d not found", id))); Exception类 @ResponseS......

亚林瓜子
28分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部