[Python 多线程] Barrier (十一)
Barrier
栅栏,也叫屏障。可以想象成路障、道闸。
Python 3.2引入的新功能。
构造方法:
threading.Barrier(parties, action=None, timeout=None)
构建Barrier对象,parties 指定参与方数目,timeout是wait方法未指定时超时的默认值。
n_waiting 当前在栅栏中等待的线程数
parties 通过栅栏所需的线程数
wait(timeout=None) 等待通过栅栏,返回0到线程数-1的整数(barrier_id),每个线程返回不同。如果wait方法设置了超时,并超时发送,栅栏将处于broken状态。
例1:
#Barrier 栅栏
import threading,logging
logging.basicConfig(level=logging.INFO,format="[-] %(threadName)s %(message)s") def work(barrier:threading.Barrier):
logging.info("n_waiting = {}".format(barrier.n_waiting)) # 等待的线程数
bid = barrier.wait() # 参与者的id,返回0到线程数减1的数值
logging.info("after barrier {}".format(bid)) # 栅栏之后 barrier = threading.Barrier(3) # 3个参与者,每3个开闸放行,0,1,2 4,5,6 for x in range(1,4): # 所有参数者个数,4,5,6,10,15
threading.Event().wait(1)
threading.Thread(target=work,args=(barrier,),name="Barrier-{}".format(x)).start() 运行结果:
[-] Barrier-1 n_waiting = 0
[-] Barrier-2 n_waiting = 1
[-] Barrier-3 n_waiting = 2
[-] Barrier-3 after barrier 2
[-] Barrier-2 after barrier 1
[-] Barrier-1 after barrier 0
每一个进来就等待,不够3个就阻塞,直到够3个就开闸放行。
Barrier实例的方法:
broken 检测栅栏是否处于打破的状态,返回True或False
abort() 将栅栏置于broken状态,等待中的线程或者调用等待方法的线程都会抛出threading.BrokenBarrieError异常,直到reset方法来恢复栅栏
reset() 恢复栅栏,重新开始拦截
例2:
#Barrier 栅栏
import threading,logging
logging.basicConfig(level=logging.INFO,format="[-] %(threadName)s %(message)s") def work(barrier:threading.Barrier):
logging.info("n_waiting = {}".format(barrier.n_waiting))
try:
bid = barrier.wait()
logging.info("after barrier {}".format(bid))
except threading.BrokenBarrierError:
logging.info("Broken Barrier in {}".format(threading.current_thread())) barrier = threading.Barrier(3) for x in range(1,12): #12个
if x == 3:
barrier.abort() #有一个人坏了规矩
elif x == 6:
barrier.reset()
threading.Event().wait(1)
threading.Thread(target=work,args=(barrier,),name="Barrier-{}".format(x)).start() 运行结果:
[-] Barrier-1 n_waiting = 0 #0,1
[-] Barrier-2 n_waiting = 1
[-] Barrier-2 Broken Barrier in <Thread(Barrier-2, started 3124)>
[-] Barrier-1 Broken Barrier in <Thread(Barrier-1, started 8036)>
[-] Barrier-3 n_waiting = 0
[-] Barrier-3 Broken Barrier in <Thread(Barrier-3, started 7428)>
[-] Barrier-4 n_waiting = 0
[-] Barrier-4 Broken Barrier in <Thread(Barrier-4, started 1828)>
[-] Barrier-5 n_waiting = 0
[-] Barrier-5 Broken Barrier in <Thread(Barrier-5, started 7416)>
[-] Barrier-6 n_waiting = 0 #6,7,8
[-] Barrier-7 n_waiting = 1
[-] Barrier-8 n_waiting = 2
[-] Barrier-8 after barrier 2
[-] Barrier-7 after barrier 1
[-] Barrier-6 after barrier 0
[-] Barrier-9 n_waiting = 0 #9,10,11
[-] Barrier-10 n_waiting = 1
[-] Barrier-11 n_waiting = 2
[-] Barrier-11 after barrier 2
[-] Barrier-9 after barrier 0
[-] Barrier-10 after barrier 1
一共有12个参与者,依次开始,1和2处于等待状态,到达第3的时候,进入了broken状态,则直到第6个,才恢复栅栏,从6开始继续拦截,达到3个(6,7,8)就放行,9,10,11也放行。
例3:
wait方法
#Barrier 栅栏
import threading,logging
logging.basicConfig(level=logging.INFO,format="[-] %(threadName)s %(message)s") def work(barrier:threading.Barrier,i:int):
logging.info("n_waiting = {}".format(barrier.n_waiting))
try:
if i < 3:
bid = barrier.wait(1) #超时1秒就将栅栏置于broken状态,抛出异常后续语句不会执行
else:
if i == 6:
barrier.reset() #恢复栅栏
bid = barrier.wait()
# logging.info("broken status = {}".format(barrier.broken)) #是否处于broken状态
logging.info("after barrier {}".format(bid))
except threading.BrokenBarrierError:
logging.info("Broken Barrier in {}".format(threading.current_thread())) barrier = threading.Barrier(3) for i in range(1,11): #10个
threading.Event().wait(2) #强制延迟2秒,让出时间片
threading.Thread(target=work,args=(barrier,i),name="Barrier-{}".format(i)).start() 运行结果:
[-] Barrier-1 n_waiting = 0
[-] Barrier-1 Broken Barrier in <Thread(Barrier-1, started 3100)>
[-] Barrier-2 n_waiting = 0
[-] Barrier-2 Broken Barrier in <Thread(Barrier-2, started 8836)>
[-] Barrier-3 n_waiting = 0
[-] Barrier-3 Broken Barrier in <Thread(Barrier-3, started 8428)>
[-] Barrier-4 n_waiting = 0
[-] Barrier-4 Broken Barrier in <Thread(Barrier-4, started 1204)>
[-] Barrier-5 n_waiting = 0
[-] Barrier-5 Broken Barrier in <Thread(Barrier-5, started 1556)>
[-] Barrier-6 n_waiting = 0
[-] Barrier-7 n_waiting = 1
[-] Barrier-8 n_waiting = 2
[-] Barrier-8 after barrier 2
[-] Barrier-7 after barrier 1
[-] Barrier-6 after barrier 0
[-] Barrier-9 n_waiting = 0
[-] Barrier-10 n_waiting = 1
阻塞中
wait方法在等待超时1秒后,就强制将栅栏置于broken状态,直到第6个的时候才reset恢复,然后6,7,8放行,9,10,继续阻塞。如果此时有第11个,就会9,10,11放行。
应用场景:
并发初始化
所有线程都必须初始化完成后,才能继续工作,例如运行前加载数据,检查,如果这些工作没完成就不能正常工作运行。
10个线程做10种工作准备,每个线程负责一种工作,只有10个线程都完成后,才能继续工作,先完成的要等待后完成的线程。
例如,启动一个程序,需要先加载磁盘文件、缓存预热、初始化连接池等工作,这些工作可以齐头并进,不过只有都满足了,程序才能继续向后执行。假设数据库链接失败,则初始化工作失败,就要abort,栅栏broken,所有线程收到异常退出。
工作量
有10个计算任务,完成6个,就算工作完成。
PPTBYG
[Python 多线程] Barrier (十一)的更多相关文章
- Python多线程-Barrier(障碍对象)
Barrier(parties, action=None, timeout=None) 每个线程通过调用wait()尝试通过障碍,并阻塞,直到阻塞的数量达到parties时,阻塞的线程被同时全部释放. ...
- Day9 - Python 多线程、进程
Python之路,Day9, 进程.线程.协程篇 本节内容 操作系统发展史介绍 进程.与线程区别 python GIL全局解释器锁 线程 语法 join 线程锁之Lock\Rlock\信号量 将线 ...
- 搞定python多线程和多进程
1 概念梳理: 1.1 线程 1.1.1 什么是线程 线程是操作系统能够进行运算调度的最小单位.它被包含在进程之中,是进程中的实际运作单位.一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发 ...
- 浅析Python多线程
学习Python多线程的资料很多,吐槽Python多线程的博客也不少.本文主要介绍Python多线程实际应用,且假设读者已经了解多线程的基本概念.如果读者对进程线程概念不甚了解,可参见知名博主 阮一峰 ...
- python多线程和多进程
1 概念梳理: 1.1 线程 1.1.1 什么是线程 线程是操作系统能够进行运算调度的最小单位.它被包含在进程之中,是进程中的实际运作单位.一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发 ...
- Python 多线程、进程
本节内容 操作系统发展史介绍 进程.与线程区别 python GIL全局解释器锁 线程 语法 join 线程锁之Lock\Rlock\信号量 将线程变为守护进程 Event事件 queue队列 生产者 ...
- python 多线程示例
原文链接:http://www.cnblogs.com/whatisfantasy/p/6440585.html 1 概念梳理: 1.1 线程 1.1.1 什么是线程 线程是操作系统能够进行运算调度的 ...
- Python多线程、进程、协程
本节内容 操作系统发展史介绍 进程.与线程区别 python GIL全局解释器锁 线程 语法 join 线程锁之Lock\Rlock\信号量 将线程变为守护进程 Event事件 queue队列 生产者 ...
- 转搞定python多线程和多进程
转自https://www.cnblogs.com/whatisfantasy/p/6440585.html 1 概念梳理: 1.1 线程 1.1.1 什么是线程 线程是操作系统能够进行运算调度的最小 ...
随机推荐
- 撩课-Java每天10道面试题第7天
撩课Java+系统架构 视频 点击开始学习 61.什么是并发修改异常? 什么是并发修改异常: 当我们在遍历实现了collection接口 与iterator接口的集合时(List.Set.Map), ...
- spring底层原理解析
注解测试:如何使用注解(去掉配置文件)开发 新建MainConfig类 注解测试:新建MainTest2注解测试,用来测试//AnnoatationConfigApplicationContext: ...
- java加载redis以及基本操作
前言: Redis是一款开源的.高性能的键-值存储(key-value store).它常被称作是一款数据结构服务器(data structure server).Redis的键值可以包括字符串(st ...
- Java实现类似类似百度搜索模糊关键字
package com.test; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedHashM ...
- async await的使用
var sleep = function (time) { return new Promise(function (resolve, reject) { setTimeout(function () ...
- 【Html基础】之<h1>~<h6> <p> <br> <hr>
学习html无从下手,就在w3school的html手册按着教程学习了下. 什么是html? html是指超文本标记语言,即Hyper Text Markup Language html不是一种编程语 ...
- Flutter知识点:数据存储之sqflite
sqflite是一款轻量级的关系型数据库,类似SQLite. 在Flutter平台我们使用sqflite库来同时支持Android 和iOS. 使用介绍 1.首选需要在pubspec.yaml 导入库 ...
- 1 win10双系统安装ubuntu16.04和18.04(问题详细记录)
我从来不想在琐事上花功夫.就拿装系统来说,我感觉拿过来一个完全陌生的项目源码,看起来,都比装系统爽.我属于典型的逻辑思考男.喜欢畅游程序的海洋. 一直windows跑深度学习和tensorflow,有 ...
- 修改maven默认的jdk版本
修改maven默认的jdk版本,想改彻底需要在maven的全局配文件(settings.xml)增加以下信息: 在profiles 节点下增加: <profile> <id> ...
- 常用的自动化测试框架及测试框架的发展(Alpha)
前言:自动化测试在过去的20年已经有了很大的发展.最初的测试工具只提供了简单的捕捉/回访功能,维护性较差.而且脚本工具实现需要很强的开发技术和经验,而且数量众多的测试脚本加上没有文档记录因此维护起来较 ...