pthread_cond_broadcast & pthread_cond_signal
pthread_cond_broadcast(&cond1)的作用是唤醒所有正在pthread_cond_wait(&cond1,&mutex1)的线程。
pthread_cond_signal(&cond1)的的作用是唤醒所有正在pthread_cond_wait(&cond1,&mutex1)的至少一个线程。(虽然我还没碰到过多于一个线程的情况,但是man帮组手册上说的是至少一个)
下面分为情况讨论一下这两个函数的效果。
第一种情况:多个线程等待同一个cond,并且想对同一个mutex加锁。
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <stdlib.h> pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER; void* thread_task1(void* arg)
{
pthread_mutex_lock(&mutex1); pthread_cond_wait(&cond,&mutex1); printf("thread_task1 start working\n");
sleep();
printf("thread_task1 works over\n");
pthread_mutex_unlock(&mutex1); return NULL; } void* thread_task2(void* arg)
{
pthread_mutex_lock(&mutex2); pthread_cond_wait(&cond,&mutex2); printf("thread_task2 start working\n");
sleep();
printf("thread_task2 works over\n");
pthread_mutex_unlock(&mutex2); return NULL; } void* broadcastDiffMutex(void* arg)
{
pthread_cond_broadcast(&cond);
return NULL; } void* signalDiffMutex(void* arg)
{
pthread_cond_signal(&cond);
return NULL; } int main()
{
pthread_t thread_1,thread_2,thread_3;
pthread_create(&thread_1,NULL,thread_task1,NULL);
pthread_create(&thread_2,NULL,thread_task2,NULL);
sleep(); #ifdef SIGNAL
pthread_create(&thread_3,NULL,signalDiffMutex,NULL);
#else
pthread_create(&thread_3,NULL,broadcastDiffMutex,NULL);
#endif pthread_join(thread_1,NULL);
pthread_join(thread_2,NULL);
pthread_join(thread_3,NULL); return ; }
使用broadcast的运行结果:

使用signal的运行结果:

分析:
- 当使用broadcast方式时,两个被阻塞的线程都被唤醒了,被唤醒的线程将变为pthread_mutex_lock(mutex1)的状态,他们将抢着对mutex1加锁,在本次运行过程中thread_1加锁成功了,thread_2没有成功抢到锁,于是它就被阻塞了,在thread_1执行完毕释放锁后,会通知所有被阻塞在mutex1上的线程,于是thread_2最终成功拿到了锁,然后顺利执行。
- 当使用signal方式时,thread_1和thread_2中只被唤醒了一个线程,在本次运行中是thread_1被唤醒了,而因为thread_2没有被唤醒,他就一直卡在pthread_cond_wait处呼呼大睡,所以最终只有thread_1执行完毕。
第二种情况:多个线程等待同一个cond,并且分别不同的mutex加锁。
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <stdlib.h> pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER; void* thread_task1(void* arg)
{
pthread_mutex_lock(&mutex1); pthread_cond_wait(&cond,&mutex1); printf("thread_task1 start working\n");
sleep();
printf("thread_task1 works over\n");
pthread_mutex_unlock(&mutex1); return NULL; } void* thread_task2(void* arg)
{
pthread_mutex_lock(&mutex2); pthread_cond_wait(&cond,&mutex2); printf("thread_task2 start working\n");
sleep();
printf("thread_task2 works over\n");
pthread_mutex_unlock(&mutex2); return NULL; } void* broadcastDiffMutex(void* arg)
{
pthread_cond_broadcast(&cond);
return NULL; } void* signalDiffMutex(void* arg)
{
pthread_cond_signal(&cond);
return NULL; } int main()
{
pthread_t thread_1,thread_2,thread_3;
pthread_create(&thread_1,NULL,thread_task1,NULL);
pthread_create(&thread_2,NULL,thread_task2,NULL);
sleep(); #ifdef SIGNAL
pthread_create(&thread_3,NULL,signalDiffMutex,NULL);
#else
pthread_create(&thread_3,NULL,broadcastDiffMutex,NULL);
#endif pthread_join(thread_1,NULL);
pthread_join(thread_2,NULL);
pthread_join(thread_3,NULL); return ; }
使用broadcast的效果:

使用signal的效果

分析:
- 当使用broadcast方式时,因为两个线程都被唤醒了,且它们想要加的锁并没有竞争关系,因此它们是并发执行的,而不必像前一种情况中那样必须一前一后执行。
- 当使用signal方式时,只被唤醒了一个线程,因此只有一个线程成功执行。
pthread_cond_broadcast & pthread_cond_signal的更多相关文章
- (九) 一起学 Unix 环境高级编程 (APUE) 之 线程
. . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...
- Unix网络编程第三版源码编译
配置: $ cd Unix-Network-Programming/ $ chmod 755 configure $ ./configure 主要的工作是检查系统是否有源码编译所依赖的各种资源(系统版 ...
- Why does pthread_cond_signal not work?【转】
转自:http://stackoverflow.com/questions/16819169/why-does-pthread-cond-signal-not-work# 0 down vote fa ...
- 深入理解pthread_cond_wait、pthread_cond_signal
===============================man pthread_cond_wait的解释========================== LINUX环境下多线程编程肯定会遇到 ...
- 线程相关函数(6)-pthread_cond_wait(),pthread_cond_signal(), 条件变量
pthread_cond_tpthread_cond_initpthread_cond_destroypthread_cond_waitpthread_cond_timedwaitpthread_co ...
- 条件变量pthread_cond_wait()和pthread_cond_signal()详解
条件变量 条件变量是利用线程间共享的全局变量进行同步的一种机制,主要包括两个动作:一个线程等待"条件变量的条件成立"而挂起:另一个线程使"条件成立" ...
- pthread_cond_signal与pthread_cond_wait详解
转:http://blog.chinaunix.net/uid-11572501-id-3456343.html //pthread_cond_signal 只发信号,内部不会解锁,在Linux 线程 ...
- pthread_cond_signal惊群现象
1.如下代码所示: #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include < ...
- 关于 pthread_cond_wait 和 pthread_cond_signal , signal 无效的问题
关于一个消费者模式,,,引起的问题.. 我在io线程里不断的把一个函数调用放到队列里 然后ruby线程就不断的从这个队列里取出函数之争并运行. 典型的 消费者模式. 我曾经以为是这样... 这是wor ...
随机推荐
- 【转】最简单的安装pip的方法
网上有各种方法安装pip,针对不同的系统方法还不一样,最后发现还是下面这种方法最简单,直接了当干脆方便,适用于Windows和Linux. (1)下载pip 进入https://pypi.python ...
- Idea 注册方式,亲测可用
参考:https://www.cnblogs.com/aacoutlook/p/9036299.html 2018年3月 <License server>方式不能使用了,只好尝试<A ...
- 深度学习论文翻译解析(七):Support Vector Method for Novelty Detection
论文标题:Support Vector Method for Novelty Detection 论文作者:Bernhard Scholkopf, Robert Williamson, Alex Sm ...
- 【LC_Lesson1】--字符串反转练习
LeetCode算法练习题目一: 给定一个字符串,要求将该字符串反转后输出 努力学习,天天向上.借助LeetCode的题目,练习编码能力,数据结构,以及C++和Python的编码能力. 一. 算法实现 ...
- Spring Boot 事务的使用
Spring Boot 使用事务非常简单,首先使用注解 @EnableTransactionManagement 开启事务支持后,然后在访问数据库的Service方法上添加注解 @Transactio ...
- 月薪30k的Java架构师JVM常见面试题解析
在做程序员的路上经常会遇到的JVM一些经典面试题,今天给大家分享出我自己的解题思路,希望对大家有帮助,后续有空会持续更新. 1.什么情况下会发生栈内存溢出. 思路: 描述栈定义,再描述为什么会溢出,再 ...
- 【转】oracle条件子句执行顺序
Oracle WHERE条件执行顺序:ORACLE采用自下而上的顺序解析WHERE子句 1.据此那些可以过滤掉最大数量记录的条件必须写在WHERE子句的末尾例如:SELECT … FROM EMP E ...
- leetcode 最大水池
leetcode 11题 水池最大容积 题目描述 给定 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) .在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 ( ...
- ancconda创建爬虫项目
# 安装 conda env list conda create -n <envname> conda activate <envname> conda install scr ...
- C0nw4y's L!f3 G4me 代码实现
这是我转载的博客,关于这个游戏的介绍.估计没人能get到这个游戏的blingbling的地方吧.还是蛮惊叹的. 因为这里网络实在惨淡,闲来无事实现了下这个游戏,UI尽量美化了,可惜python配置不知 ...