Python 多线程编程-07-threading 模块 - Barrier

目录

1. threading.Barrier

1.1 threading.Barrier作用

1.2 threading.Barrier 构造函数

1.2.1 threading.Barrier 构造方法

1.2.2 threading.Barrier 参数列表

1.3 threading.Barrier 属性和方法

1.4 threading.Barrier 使用示范

1.4.1 简单的控制同时运行的线程数量

1.4.2 使用 timeout 控制等待时间

1.4.3 使用 Barrier 中的 action 参数


Python 多线程编程目录

Python 多线程编程-01-threading 模块初识

Python 多线程编程-02-threading 模块-锁的使用

Python 多线程编程-03-threading 模块 - Condition

Python 多线程编程-04-threading 模块 - Event

Python 多线程编程-05-threading 模块 - Semaphore 和 BoundedSemaphore

Python 多线程编程-06-threading 模块 - Timer

Python 多线程编程-07-threading 模块 - Barrier

1. threading.Barrier

1.1 threading.Barrier 作用

        Barrier 即栅栏的意思,可以想象成路障、道闸,它是 Python 3.2 引入的新功能。

        在 Python 多线程编程-05-threading 模块 - Semaphore 和 BoundedSemaphore 中曾经提过,使用 Semaphore 或者是 BoundedSemaphore 可以控制线程的最多数量。threading.Barrier 也可以起到控制线程的作用,但它不是控制上限,而是控制下限,即满足到一定数量才能进行。

        具体机制:

        每个线程通过调用 wait() 尝试通过 Barrier,如果不能通过,则阻塞;直到阻塞的线程数量达到了 parties 时候,阻塞的线程被全部释放。如果 Barrier 里面设置了 timeout,那么阻塞时间超过 timeout 时候则报错。

1.2 threading.Barrier 构造函数

1.2.1 threading.Barrier 构造方法

        threading.Barrier 的构造方法如下:

barrier = Barrier(parties, action=None, timeout=None)

1.2.2 threading.Barrier 参数列表

  1. parties:控制的线程数,即设置的 Barrier 能够通过的线程数最小值;
  2. action:是一个可调用函数,当等待的线程到达了线程障碍数量 parties,其中一个线程会首先调用 action 对应函数,之后再执行线程自己内部的代码;
  3. timeout:默认的超时时间

1.3 threading.Barrier 属性和方法

threading.Barrier 属性和方法
序号属性和方法描述
1方法 abort()

将障碍置为断开状态,这将导致已调用 wait() 或之后调用 wait()

的线程触发 BrokenBarrierError

2属性 broken布尔值,刚刚创建 barrier 时候barrier.broken  为 False,如果调用了 barrier.abort(),barrier.broken 则为 True
3属性 n_waiting当前在屏障中等待的线程数,一般在 wait() 方法前可能为非 0, wait() 方法成功后为 0
4属性 parties通过障碍所需的线程数。
5方法 reset()重置该 Barrier 回初始状态;所有正在 wait() 的线程会得到 BrokenBarrier exception。
6方法wait(timeout=None)每个线程通过调用 wait() 尝试通过 Barrier,如果不能通过,则阻塞;直到阻塞的线程数量达到了 parties 时候,阻塞的线程被全部释放。如果 Barrier 里面设置了 timeout,那么阻塞时间超过 timeout 时候则报错。

1.4 threading.Barrier 使用示范

1.4.1 简单的控制同时运行的线程数量

设计了一段代码,只有满足了三个线程才会通过 Barrier,而我只给了5个线程,所以可以看到,前面三个线程得到了执行,后面的两个线程都在持续等待中。

import threading
import time
words=["a","12","你好!","春风十里","一起向未来"]
thread_list=[]
barrier=threading.Barrier(3)

def show_time(word):
    print("Coming in show time ==>",word)
    barrier.wait()
    print(time.ctime()+"==>"+word)
    
for word in words:
    t=threading.Thread(target=show_time,args=(word,))
    thread_list.append(t)
    
for thread in thread_list:
    thread.start()

for thread in thread_list:
    thread.join()

print(time.ctime()+" All done!")

运行结果:

如果线程数调整为 6 那么后面三个线程也会被执行。

import threading
import time
words=["a","12","你好!","春风十里","一起向未来","结束了"]
thread_list=[]
barrier=threading.Barrier(3)

def show_time(word):
    print("Coming in show time ==>",word)
    barrier.wait()
    print(time.ctime()+"==>"+word)
    
for word in words:
    t=threading.Thread(target=show_time,args=(word,))
    thread_list.append(t)
    
for thread in thread_list:
    thread.start()

for thread in thread_list:
    thread.join()

print(time.ctime()+" All done!")

运行结果

        从上面的运行结果也可以看出,虽然所有的线程都被执行了,但是同一批线程彼此之间执行的顺序是不确定的。

1.4.2 使用 timeout 控制等待时间

         从 1.4.1 可以看到,如果迟迟没有等待足够的线程,部分程序可能会一直阻塞,这时候需要一定的 timeout 机制,来阻止这种无休止的等待。

        只需要修改 barrier.wait 方法就可以,加入timeout 参数为4,即最多等待 4秒。

        代码修改如下:

words=["a","12","你好!","春风十里","一起向未来"]
thread_list=[]
barrier=threading.Barrier(3)

def show_time(word):
    print("Coming in show time ==>",word)
    barrier.wait(4)
    print(time.ctime()+"==>"+word)
    
for word in words:
    t=threading.Thread(target=show_time,args=(word,))
    thread_list.append(t)
    
for thread in thread_list:
    thread.start()

for thread in thread_list:
    thread.join()

print(time.ctime()+" All done!")

运行结果如下,当超时后,就会报错 “threading.BrokenBarrierError” 

可以使用 try 机制来避免程序中断。

words=["a","12","你好!","春风十里","一起向未来"]
thread_list=[]
barrier=threading.Barrier(3)

def show_time(word):
    print("Coming in show time ==>",word)
    try:
        barrier.wait(4)
        print(time.ctime()+"==>"+word)
    except threading.BrokenBarrierError:
        print("The threading is time out and the word {0} will not be shown!".format(word))
    
for word in words:
    t=threading.Thread(target=show_time,args=(word,))
    thread_list.append(t)
    
for thread in thread_list:
    thread.start()

for thread in thread_list:
    thread.join()

print(time.ctime()+" All done!")

 运行结果如下:

这个 timeout 也可以在构造 Barrier 时候就设置,就不需要在调用 wait()方法时候再设置了。

  

如果 Barrier 在构建时候设置了 timeout ,在调用 wait() 方法时候也设置了不同的 timeout 参数,那么以 wait() 时候为准。

words=["a","12","你好!","春风十里","一起向未来"]
thread_list=[]
barrier=threading.Barrier(3,timeout=4)

def show_time(word):
    print("Coming in show time ==>",word)
    try:
        barrier.wait(5)
        print(time.ctime()+"==>"+word)
    except threading.BrokenBarrierError:
        print("The threading is time out and the word {0} will not be shown!".format(word))
    
for word in words:
    t=threading.Thread(target=show_time,args=(word,))
    thread_list.append(t)
    
for thread in thread_list:
    thread.start()

for thread in thread_list:
    thread.join()

print(time.ctime()+" All done!")

 运行结果如下:

1.4.3 使用 Barrier 中的 action 参数

使用 Barrier 中的 action 参数,可以在每次放过一批线程时候做一些操作。

import threading
import time
words=["a","12","你好!","春风十里","一起向未来","最后一个"]
show_time_list=[]


class Show_Time(threading.Thread):
    def __init__(self,barrier,word=None):
        super().__init__()
        self.barrier=barrier
        self.word=word
    
    def run(self):
        self.barrier.wait()
        print(time.ctime()+"==>"+self.word)
        

def ok():
    print("I am OK!")
    
barrier=threading.Barrier(3,action=ok)

for word in words:
    t=Show_Time(barrier,word)
    show_time_list.append(t)
    
for thread in show_time_list:
    thread.start()

for thread in show_time_list:
    thread.join()

print(time.ctime()+" All done!")

运行结果如下:

'''

要是大家觉得写得还行,麻烦点个赞或者收藏吧,想个博客涨涨人气,非常感谢!

'''

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

江南野栀子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值