barrier可以理解为是屏障,是阻碍你前行的
3.2引入的新功能,parties参与方,action做什么动作
等待数,要几个人参与,等待几个人
类似赛车,开始都在起点等,等都到齐了再跑,需要等到所有参赛方都到齐了才开始,拦起来,等待所有的参与方到齐,这就是barrier
wait不超时
启动一个线程,但是要求参与方是三个
等到条件成熟才能结束
改成2就是2个参与方
条件满足这一句就执行了,都跑起来了,等待的就没几个
参与方不够是可以看到n.waiting的,参与方等待数一旦达到,会立即执行
barrier,可以在一些场景下:
比如有些事可以并发一起做,但是这几个条件满足以后,才能做下面的事情,第一阶段4个事情做完都在wait,条件触发进行第二阶段的事情
这是继续向后执行,但是全出问题了
因为一旦barrier.abort()打破以后,下面一句抛出异常,brokenbarriererror,一个破了的barrier,表示屏障是一个打破的状态
在后面再进行修改,broken是true了
这样加了以后,当i=0,1,2正好第三个的时候打破了,打破了之后,barrier处于一种状态,叫broken状态,这种状态barrier是不能正常工作的,也就是直接访问get,是get不了的
要修复下barrier
reset是恢复到初始的状态的
起来6个线程,两个在等,barrier是恢复了,但是前面的异常已经抛出去了,前面的在你打破到恢复之间的线程,这些线程wait了就崩了
出了问题,现在语句里也没有上下文管理,try,finally
起9个线程,456,789都可以,崩掉三个,有些任务可以完成
正好,这样就没有等待了,中间是可以把barrier,broken的
barrier在使用的时候,由于某种情况,可能会导致barrier 变成broken了,在适当的情况下,需要reset,有下面两个方法使用,但是一般都不使用,barrier只要是brokern状态都无法正常使用
如果要使用的话,加try和finally抛出的异常现在在threading里面,不在builtin里面,这个异常属于线程中的barrier要使用的,是放在threading模块中的
runtimeerror异常的祖先类就是exception
这就是运行时产生的异常,barrier是大家都在等,等到参与方都齐了,然后一起开始工作,barrier不关心线程是否重新使用,只关心,要不要wait,按照现在调用,wait方都会阻塞,只关心等的人够不够
现在修改成这样
wait(1)秒,这就是一种超时的判断。超时就抛异常
执行这一句说明抛出异常了
如果在指定的时间内没有等到参与方都到齐,当前barrier直接broken,如果不reset是没办法继续执行的,不reset,相当于没有消耗掉barrier,是不能用的
一旦通过某些语句,导致了barrier超时了,这个barrier就处于一种不能工作的broken状态,必须手动调用reset恢复,否则barrier不能用 了,不管是手动打破还是超时打破,barrier不能正常工作,要使用barrier就必须reset,将它重置,这个时候broken就是false(说明现在不是broken,说明现在是可以工作的,barrier现在是一种正常状态)
barrier的超时是回抛出异常的,不仅会抛出异常,还会把当前barrier打破,处于broken状态,而且broken状态必须reset,没有reset恢复不了(barrier,就abort和n.waiting,构造方法,reset,就这几个)
wait会返回一个id,相当于永久阻塞,如果wait成功,返回一个id,如果wait不成功,就不返回id(wait超时,要么false,要么不成功)
一直等,等到返回barrier_id 为止,要么抛出异常,刚才打印看到的数值就是barrier_id
broken状态,必须reset来使用,如果broken,状态就不能abort使用,会抛出brokenBarrierError异常wait方法,是超时发生之后,屏障就处于broken状态,borken状态只能由reset恢复
只有超时,没有阻塞不阻塞的东西
这个方法可能产生这个异常,当下已经是broken,这个就没法用
现在修改成这样
查看这个一个线程,线程,启动,wait两秒,打印里面的波浪线
如果没等到,不是返回一个barrier_ID
barrier应用
并发初始化,
所有线程都必须初始化完成后,才能继续工作,例如运行前加载数据、检查,如果这些工作没完成,就开始运行,将不能正常工作。
10个线程做10种工作准备,每个线程负责一种工作,只有这10个线程都完成后,才能继续工作,先完成的要等待后完成的线程。
把123做完才能做到4
**前面的这几部工作,都需要wait,读取文件,建立数据库链接都要做好,才能对外服务,现在的这些准备工作可以并行处理,处理完,条件都具备了,才能真正运行下一步,这时候需要barrier来处理,失败了就abort,所有的barrier,wait不下去了,刚才等,如果把屏障打破了,就没必要等了,屏障就从当前的broken状态变成非broken状态,等待就没有用了
**
这些线程本来在等,由于某一个线程执行失败之后,手动barrier来abort,如果前两步做好了,数据库链接没成功,就直接把barrier 变abort了(刚才在等的已经没有意义了,也会抛出异常,因为在barrier上去wait,wait以后就会抛出异常,brokenbaiiererror,然后该对线程做什么处理就做什么处理,最后整个程序退出)
并行处理后,当条件都具备进行下一步
还有一种就是工作量的问题,有10个完成6个即可
barrier会抛出异常,异常恢复,需要reset,不reset,回去不了,barrier就处于一种异常状态,broken状态,原来等待也会出问题,是跟event相关的