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. eclipse中使用postgreSQL报错( Cannot load JDBC driver class )

    需求: 使用Maven插件调用PostgreSQL数据库 环境: eclipse_4.5.0+JDK_1.7+Tomcat_7.0+Maven+postgresql-9.1-901.jdbc4.jar ...

  2. C#调用JS的WebService的方法返回null

    连上了别人的VPN后,使用WebService测试软件测试了一下,结果正常,但是当我在vs里面添加WebService服务,调用的时候就出现了问题,问题如下图: 后来问了一下服务端那边的同事,他们说服 ...

  3. 手抖把Python2.7卸载了,导致了自己的yum不可用以及yum因python版本无法使用的问题

    摘要: 从标题就能看到我有多心如死灰了,简单介绍下我是如何自残的过程. ①首先因为需要部署爬虫程序,然后安装Python3. ②Python3系列和Python2系列版本不向下兼容,所以我就卸载了机器 ...

  4. C#登出系统并清除Cookie

    1.前端页面代码: 前端页面代码主要显示退出系统或者网站的可视化按钮代码,代码如下:(请忽略项目关键字:CPU) <ul class="nav navbar-nav navbar-ri ...

  5. cogs 1361. 树 线段树

    1361. 树 ★   输入文件:treed.in   输出文件:treed.out   简单对比时间限制:1 s   内存限制:128 MB [问题描述] 在一个凉爽的夏夜,xth和rabbit来到 ...

  6. 如何实施DevOps

    对于长期在孤立的架构下工作的组织来说,转移到协作式DevOps系统似乎是难以成功的.为了进一步提高效率,必须改变观念,并进行团队文化改变.例如:许多人认为只有自动化工具才能解决DevOps,其实这是不 ...

  7. java架构之路(多线程)JUC并发编程之Semaphore信号量、CountDownLatch、CyclicBarrier栅栏、Executors线程池

    上期回顾: 上次博客我们主要说了我们juc并发包下面的ReetrantLock的一些简单使用和底层的原理,是如何实现公平锁.非公平锁的.内部的双向链表到底是什么意思,prev和next到底是什么,为什 ...

  8. Jenkins Job构建

    Jenkins job介绍 ​ Jenkins Freestyle与Pipeline Job区别 ​ ​ Jenkins Job构建配置 一 .环境准备 1.配置Jenkins server本地Git ...

  9. 【java面试】集合类篇

    java中主要的类集合接口如下 Collection ├List │├LinkedList │├ArrayList │└Vector │ └Stack └Set Map ├Hashtable ├Has ...

  10. 10、python函数

    前言:本文主要介绍python函数的定义和调用.函数的参数.函数的作用域.内置函数. 一.函数的定义和调用 1.函数的作用 对特定的一些功能进行封装,提高代码的重用率,进而提升开发的效率,格式: de ...