多线程(18) pthread_cond_broadcast
多线程(18) pthread_cond_broadcast
- 1. pthread_cond_broadcast 唤醒所有被阻塞的线程
- 1.1 pthread_cond_broadcast 和 pthread_cond_signal
- 2. 代码例子说明
- 2.1 情况1:多个线程等待同一个cond,并且想对同一个mutex加锁。
- 2.1.1 使用 pthread_cond_signal 通知
- 2.1.2 使用 pthread_cond_broadcast 通知
- 2.1.3 分析:
- 2.2 情况2:多个线程等待同一个cond,并且分别不同的mutex加锁。
- 2.2.1 使用 pthread_cond_signal 通知
- 2.2.2 使用 pthread_cond_broadcast 通知
- 2.2.3 分析:
- 3.问题: 未解决,加printf 就不能通知
- 参考
1. pthread_cond_broadcast 唤醒所有被阻塞的线程
1.1 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帮组手册上说的是至少一个)
2. 代码例子说明
2.1 情况1:多个线程等待同一个cond,并且想对同一个mutex加锁。
2.1.1 使用 pthread_cond_signal 通知
代码:
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <stdlib.h>#define SIGNAL 1pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;void* thread_task1(void* arg)
{pthread_mutex_lock(&mutex1);pthread_cond_wait(&cond,&mutex1);printf("thread_task1 start working\n");sleep(2);printf("thread_task1 works over\n");pthread_mutex_unlock(&mutex1);return NULL;
}void* thread_task2(void* arg)
{pthread_mutex_lock(&mutex1);pthread_cond_wait(&cond,&mutex1);printf("thread_task2 start working\n");sleep(2);printf("thread_task2 works over\n");pthread_mutex_unlock(&mutex1);return NULL;
}void* broadcastNotifyMutex(void* arg)
{pthread_cond_broadcast(&cond);return NULL;
}void* signalNotifyMutex(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(2);#ifdef SIGNALpthread_create(&thread_3,NULL,signalNotifyMutex,NULL);
#elsepthread_create(&thread_3,NULL,broadcastNotifyMutex,NULL);
#endifpthread_join(thread_1,NULL);pthread_join(thread_2,NULL);pthread_join(thread_3,NULL);return 0;
}
结果:
[root@localhost test]# gcc b1.c -pthread
[root@localhost test]# ./a.out
thread_task1 start working
thread_task1 works over
^C
[root@localhost test]#
2.1.2 使用 pthread_cond_broadcast 通知
代码:
将上面的代码 SIGNAL 注释掉即可
//#define SIGNAL 1
结果:
[root@localhost test]# ./a.out
thread_task1 start working
thread_task1 works over
thread_task2 start working
thread_task2 works over
[root@localhost test]#
2.1.3 分析:
当使用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执行完毕。
2.2 情况2:多个线程等待同一个cond,并且分别不同的mutex加锁。
2.2.1 使用 pthread_cond_signal 通知
代码:
将2.1.1代码添加并且thread_task2 中的 mutex1 修改为 mutex2。
pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER;
结果:
[root@localhost test]# ./a.out
thread_task2 start working
thread_task2 works over
^C
[root@localhost test]#
2.2.2 使用 pthread_cond_broadcast 通知
代码:
将2.1.1代码添加并且thread_task2 中的 mutex1 修改为 mutex2。
pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER;并且将 SIGNAL 注释掉即可
//#define SIGNAL 1
结果:
[root@localhost test]# gcc b4.c -pthread
[root@localhost test]# ./a.out
thread_task1 start working
thread_task1 works over
thread_task2 start working
thread_task2 works over
[root@localhost test]#
2.2.3 分析:
当使用broadcast方式时,因为两个线程都被唤醒了,且它们想要加的锁并没有竞争关系,因此它们是并发执行的,而不必像前一种情况中那样必须一前一后执行。
当使用signal方式时,只被唤醒了一个线程,因此只有一个线程成功执行。
3.问题: 未解决,加printf 就不能通知
就是在 分别在 thread_task1 thread_task2 函数开头加下面打印,pthread_cond_broadcast 方式只有一个线程打印
printf(“111\n”);
printf(“222\n”);
参考
说明:参考代码中情况1的mutex写错了。
https://www.cnblogs.com/XiaoXiaoShuai-/p/11855408.html
多线程(18) pthread_cond_broadcast相关推荐
- PulseAudio多线程通信:pthread_cond_broadcast/pthread_cond_signal/pthread_cond_wait(九)
pthread_cond_broadcast() pthread_cond_signal() pthread_cond_wait()函数用法概述1.pthread_cond_wait() 用于阻塞当前 ...
- 《C#本质论》读书笔记(18)多线程处理
.NET Framework 4.0 看(本质论第3版) .NET Framework 4.5 看(本质论第4版) .NET 4.0为多线程引入了两组新API:TPL(Task Parallel Li ...
- Java之多线程详解
Process与Thread(进程和线程) 程序是指令和数据的集合,是一个静态的概念. 进程则是执行程序的一次过程,是动态的概念,是系统资源分配的单位. 通常一个进程中可以包含若干个线程,一个进程中至 ...
- 易语言大漠多线程易语言大漠多线程
511遇见易语言-多线程-大漠-大漠多线程 511遇见易语言多线程大漠多线程-1进程线程多线程 511遇见易语言多线程大漠多线程-2中转子程序传多参 511遇见易语言多线程大漠多线程-3线程传参数据变 ...
- 2019 Python100道 面试 题,你会几道?
0 遇到过得反爬虫策略以及解决方法? 1.通过headers反爬虫 2.基于用户行为的发爬虫:(同一IP短时间内访问的频率) 3.动态网页反爬虫(通过ajax请求数据,或者通过JavaScript生成 ...
- 最全面的Java面试题-----是你更好的掌握java知识
最全面的Java面试题-----是你更好的掌握java知识 目录 l 概念题--- 1 一. JAVA基础--- 1 1) 面向对象的特征--- 1 2) 什 ...
- 2019最新《传智教育黑马java项目实战》
1.SE基础班 1-1 Java基础语法 1-2 面向对象和封装 1-3 常用API第一部分 1-4 继承与多态 1-5 常用API第二部分 1-6 集合 1-7 异常与多线程 1-8 File类与I ...
- 如何用python自动改试卷_2019Python100道面试题,你会几道?
Apple iPhone 11 (A2223) 128GB 黑色 移动联通电信4G手机 双卡双待 4999元包邮 去购买 > 0 遇到过得反爬虫策略以及解决方法? 1.通过headers反爬虫 ...
- 2019年 阿里巴巴Python 面试必备 !100 问
0 遇到过得反爬虫策略以及解决方法? 1.通过headers反爬虫 2.基于用户行为的发爬虫:(同一IP短时间内访问的频率) 3.动态网页反爬虫(通过ajax请求数据,或者通过JavaScript生成 ...
- 511遇见易语言乐玩插件FindPic找图
乐玩插件找图.找字需要设置全局路径SetPath,当图片和辅助在同一个目录时,可以不去设置,或者在FindPic参数pic_name中使用绝对路径,也可以不设置SetPath全局路径,本课视频示范了S ...
最新文章
- c# redis hashid如何设置过期时间_Redis中Key过期策略amp;淘汰机制
- 会说话,减少奋斗30年
- 四、linux编译规则文件Makefile
- 4012最长的最短路径的求解(C++,迪杰斯特拉算法,注释全,附迪杰斯特拉算法详解文章)
- Python文件读写模式
- C# 中对于json的解析小结
- python os.path.split_Python中split()和os.path.split()
- linux使用教程_iTOP-4412-QtE系统源码以及Linux系统-wfi设置以及使用文档 - 心底狂像...
- 如何正确使用广告素材、优化Facebook广告
- 重构:改善既有代码的设计 精彩书评二
- 【水果蔬菜识别】基于matlab GUI形态学水果蔬菜识别【含Matlab源码 919期】
- [大数据]Hadoop+Storm+Spark全套入门及实战视频教程
- Oracle Instant Client
- 行人重识别论文阅读4,行人重识别实验笔记1-无锚行人搜索框架
- 弹力弹珠java_Java实现简单的弹球游戏
- 【物理】半导体物理 西安电子科技大学 柴常春等主讲-[笔记P15-P18]
- turtle之绘制美国队长的盾牌
- IP实验3:静态路由和动态路由配置
- python小项目——2048小游戏(详解)
- 什么牌子的无线耳机最好?最好的蓝牙耳机排行榜