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的运行结果:

分析:

  1. 当使用broadcast方式时,两个被阻塞的线程都被唤醒了,被唤醒的线程将变为pthread_mutex_lock(mutex1)的状态,他们将抢着对mutex1加锁,在本次运行过程中thread_1加锁成功了,thread_2没有成功抢到锁,于是它就被阻塞了,在thread_1执行完毕释放锁后,会通知所有被阻塞在mutex1上的线程,于是thread_2最终成功拿到了锁,然后顺利执行。
  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的效果

 分析:

  1. 当使用broadcast方式时,因为两个线程都被唤醒了,且它们想要加的锁并没有竞争关系,因此它们是并发执行的,而不必像前一种情况中那样必须一前一后执行。
  2. 当使用signal方式时,只被唤醒了一个线程,因此只有一个线程成功执行。

  

pthread_cond_broadcast & pthread_cond_signal的更多相关文章

  1. (九) 一起学 Unix 环境高级编程 (APUE) 之 线程

    . . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...

  2. Unix网络编程第三版源码编译

    配置: $ cd Unix-Network-Programming/ $ chmod 755 configure $ ./configure 主要的工作是检查系统是否有源码编译所依赖的各种资源(系统版 ...

  3. Why does pthread_cond_signal not work?【转】

    转自:http://stackoverflow.com/questions/16819169/why-does-pthread-cond-signal-not-work# 0 down vote fa ...

  4. 深入理解pthread_cond_wait、pthread_cond_signal

    ===============================man pthread_cond_wait的解释========================== LINUX环境下多线程编程肯定会遇到 ...

  5. 线程相关函数(6)-pthread_cond_wait(),pthread_cond_signal(), 条件变量

    pthread_cond_tpthread_cond_initpthread_cond_destroypthread_cond_waitpthread_cond_timedwaitpthread_co ...

  6. 条件变量pthread_cond_wait()和pthread_cond_signal()详解

    条件变量        条件变量是利用线程间共享的全局变量进行同步的一种机制,主要包括两个动作:一个线程等待"条件变量的条件成立"而挂起:另一个线程使"条件成立" ...

  7. pthread_cond_signal与pthread_cond_wait详解

    转:http://blog.chinaunix.net/uid-11572501-id-3456343.html //pthread_cond_signal 只发信号,内部不会解锁,在Linux 线程 ...

  8. pthread_cond_signal惊群现象

    1.如下代码所示: #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include < ...

  9. 关于 pthread_cond_wait 和 pthread_cond_signal , signal 无效的问题

    关于一个消费者模式,,,引起的问题.. 我在io线程里不断的把一个函数调用放到队列里 然后ruby线程就不断的从这个队列里取出函数之争并运行. 典型的 消费者模式. 我曾经以为是这样... 这是wor ...

随机推荐

  1. Go Web 编程之 模板(一)

    概述 模板引擎是 Web 编程中必不可少的一个组件.模板能分离逻辑和数据,使得逻辑简洁清晰,并且模板可复用.引用第二篇文章<程序结构>一文中的图示,我们可以看到模板引擎在 Web 程序结构 ...

  2. Java项目之家庭收支记账软件

    模拟实现基于文本界面的家庭记账软件,该软件能够记录家庭的收入支出,并能够打印收支明细表. 项目采用分级菜单方式.主菜单如下: 假设家庭起始的生活基本金为10000元. 每次登记收入(菜单2)后,收入的 ...

  3. 从零开始入门 K8s | GPU 管理和 Device Plugin 工作机制

    作者 | 车漾  阿里巴巴高级技术专家 本文整理自<CNCF x Alibaba 云原生技术公开课>第 20 讲. 关注"阿里巴巴云原生"公众号,回复关键词" ...

  4. Java Collection集合概述及其常用方法

    Collection集合概述 Java数组的长度是固定的,为了使程序能够方便地存储和操作数目不固定的一组数据,JDK类库提供了Java集合 与数组不同的是,集合中不能存放基本类型数据,而只能存放对象的 ...

  5. Java 利用Map集合计算一个字符串中每个字符出现的次数

    步骤分析 1.给出一串字符串,字符串中可以包含字母.数字.符号等等. 2.创建一个Map集合,key是字符串中的字符,value是字符的个数. 3.遍历字符串,获取每一个字符. 5.使用获取到的字符, ...

  6. H5录音音频可视化-实时波形频谱绘制、频率直方图

    这段时间给GitHub Recorder开源库添加了两个新的音频可视化功能,比以前单一的动态波形显示丰富了好多(下图后两行是不是比第一行看起来丰满些):趁热打铁写了一个音频可视化相关扩展测试代码,下面 ...

  7. redis 注意事项

    1.scan_iter car_key = 'shopping*' # print(car_key) data_li = [] for i in con.scan_iter(car_key): # p ...

  8. 异步查询转同步加redis业务实现的BUG分享

    在最近的性能测试中,某一个查询接口指标不通过,开发做了N次优化,最终的优化方案如下:异步查询然后转同步,再加上redis缓存.此为背景. 在测试过程中发现一个BUG:同样的请求在第一次查询结果是OK的 ...

  9. 【java基础】String、StringBuilder和StringBuffer的区别

    关于这三个类在字符串处理中的位置不言而喻,那么他们到底有什么优缺点,到底什么时候该用谁呢?下面我们从以下几点说明一下 1.三者在执行速度方面的比较:StringBuilder >  String ...

  10. 01--java--语言概述

    啦啦啦~~~我又开始想学习了...第一次学Java... JAVA主要版本 1.Java SE(java Platform,Standard Edition) java SE以前称为J2SE.它允许开 ...