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. 初入python,与同学者的第一次见面(小激动)

    自2017来,接触python其实已经算是蛮久了,最苦的时光还是刚开始的时候,真的,我感觉编程就是一种感觉,有的时候就像找对象一样,感觉对了,怎么学都是带劲哈哈哈.在这个周围都在学习PHP的环境下,我 ...

  2. ORM基础2 字段及其参数和meta

    一.ORM简介 1.概念:ORM(Object Relational Mappingt ),对象关系映射 2.实质:类与数据库之间的映射 3.优点: 开发人员不用写数据库 4.缺点: 开发人员,数据库 ...

  3. 图像处理基础知识:EMVA1288标准之“非均匀性”的理解

    EMVA1288标准之“非均匀性”的理解 目录 1. 什么是图像的非均匀性?有标准吗? 2. EMVA1288的非均匀性内容. 3. 总结与理解 正文 1. 什么是图像的非均匀性?有标准吗?简单来说, ...

  4. Tomcat9乱码解决

    在tomcat的解压目录下找到conf,打开进入,logging.properties文件,在该文件中,修改 java.util.logging.ConsoleHandler.encoding = U ...

  5. 「 从0到1学习微服务SpringCloud 」10 服务网关Zuul

    系列文章(更新ing): 「 从0到1学习微服务SpringCloud 」06 统一配置中心Spring Cloud Config 「 从0到1学习微服务SpringCloud 」07 RabbitM ...

  6. Git The requested URL returned error:403

    一.问题描述 hexo部署的仓库需要换到另一个账号上,于是按照之前创建的步骤,修改了hexo安装目录下的deploy的repo地址,然而hexo s和hexo g没出错,但是hexo d时,会出错. ...

  7. 将DataTable数据转换成List泛型数据

    这里有一个实体类:     public class Menuss     {         public int Id { get; set; }         public string Te ...

  8. php--->查询超大文件(12G)

    今天遇到一个要在一个12G日志中查询数据的需求,手中暂时没有查询这种超大文件的工具,于是自己写了一个程度来读这个超大文件 其整体思路就是一行一行地去读取超大文件中的数据,然后将拿出的一行数据做相应的查 ...

  9. java实现字符串翻转

    public class StringReverse { /*一共写了三个函数func1 func2 func3 * 时间: 2019年9月12日9:00 * func1用的反向输出到一个新的字符串中 ...

  10. Spring注解开发系列Ⅵ --- AOP&事务

    注解开发 --- AOP AOP称为面向切面编程,在程序开发中主要用来解决一些系统层面上的问题,比如日志,事务,权限等待,Struts2的拦截器设计就是基于AOP的思想,横向重复,纵向抽取.详细的AO ...