python線程Barrier俗稱障礙對象,也稱柵欄,也叫屏障。python
# 導入線程模塊 import threading # 障礙對象barrier barrier = threading.Barrier(parties, action=None, timeout=None)
parties — 線程計數器,記錄線程數量,也稱線程障礙數量;git
action — 是一個可調用函數,當等待的線程到達了線程障礙數量parties,其中一個線程會首先調用action 對應函數,以後再執行線程本身內部的代碼;github
timeout — 默認的超時時間;微信
與以前介紹 互斥鎖Lock/事件Event/定時器Timer等不一樣,多線程Barrier會設置一個線程障礙數量parties,若是等待的線程數量沒有達到障礙數量parties,全部線程會處於阻塞狀態,當等待的線程到達了這個數量就會喚醒全部的等待線程。多線程
可能說的有點抽象,以播放器爲例子:首先一個線程作播放器初始化工做(加載本地文件或者獲取播放地址),而後一個線程獲取視頻畫面,一個線程獲取視頻聲音,只有當初始化工做完畢,視頻畫面獲取完畢,視頻聲音獲取完畢,播放器纔會開始播放,其中任意一個線程沒有完成,播放器會處於阻塞狀態直到三個任務都完成!app
wait(timeout=None) — 阻塞並嘗試經過障礙,若是等待的線程數量大於或者等於線程障礙數量parties,則表示障礙經過,執行action 對應函數並執行線程內部代碼,反之則繼續等待;ide
若是wait(timeout=None) 等待超時,障礙將進入斷開狀態!若是在線程等待期間障礙斷開或重置,此方法會引起BrokenBarrierError錯誤,注意添加異常處理,演示代碼查看案例一;函數
reset() — 重置線程障礙數量,返回默認的空狀態,即當前阻塞的線程從新來過,若是在線程等待期間障礙斷開或重置,此方法會引起BrokenBarrierError錯誤,注意添加異常處理,演示代碼查看案例二;spa
# !usr/bin/env python # -*- coding:utf-8 _*- """ @Author:何以解憂 @Blog(我的博客地址): shuopython.com @WeChat Official Account(微信公衆號):猿說python @Github:www.github.com @File:python_arbrier.py @Time:2019/10/31 21:25 @Motto:不積跬步無以致千里,不積小流無以成江海,程序人生的精彩須要堅持不懈地積累! """ # 導入線程模塊 import threading def plyer_display(): print('初始化經過完成,音視頻同步完成,能夠開始播放....') # 設置3個障礙對象 barrier = threading.Barrier(3, action=plyer_display, timeout=None) def player_init(statu): print(statu) try: # 設置超時時間,若是2秒內,沒有達到障礙線程數量, # 會進入斷開狀態,引起BrokenBarrierError錯誤 barrier.wait(2) except Exception as e: # 斷開狀態,引起BrokenBarrierError錯誤 print("等待超時了... ") else: print("xxxooooxxxxxooooxxxoooo") if __name__ == '__main__': statu_list = ["init ready","video ready","audio ready"] thread_list = list() for i in range(0,3): t = threading.Thread(target=player_init,args=(statu_list[i],)) t.start() thread_list.append(t) for t in thread_list: t.join()
輸出結果:線程
init ready
video ready
audio ready
初始化經過完成,音視頻同步完成,能夠開始播放....
xxxooooxxxxxooooxxxoooo
xxxooooxxxxxooooxxxoooo
xxxooooxxxxxooooxxxoooo
注意:若是barrier.wait(timeout=None)等待超時,會進入斷開狀態,引起BrokenBarrierError錯誤,爲了程序的健壯性,最好加上異常處理;
# 導入線程模塊 import threading def plyer_display(): print('初始化經過完成,音視頻同步完成,能夠開始播放....') # 設置3個障礙對象 barrier = threading.Barrier(3, action=plyer_display, timeout=None) def player_init(statu): while True: print(statu) try: # 設置超時時間,若是2秒內,沒有達到障礙線程數量, # 會進入斷開狀態,引起BrokenBarrierError錯誤 barrier.wait(2) except Exception as e: # 斷開狀態,引起BrokenBarrierError錯誤 # print("斷開狀態... ") continue else: print("xxxooyyyxxxooyyyxxxooyyy") break if __name__ == '__main__': statu_list = ["init ready","video ready","audio ready"] thread_list = list() for i in range(0,3): t = threading.Thread(target=player_init,args=(statu_list[i],)) t.start() thread_list.append(t) if i == 1: # 重置狀態 print("不想看愛情片,我要看愛情動做片....") barrier.reset() for t in thread_list: t.join()
輸出結果:
init ready
video ready
不想看愛情片,我要看愛情動做片....
init ready
video ready
audio ready
初始化經過完成,音視頻同步完成,能夠開始播放....
xxxooyyyxxxooyyyxxxooyyy
xxxooyyyxxxooyyyxxxooyyy
xxxooyyyxxxooyyyxxxooyyy
注意:若是barrier.wait(timeout=None)等待超時,會進入斷開狀態,引起BrokenBarrierError錯誤,爲了程序的健壯性,最好加上異常處理;
轉載請註明:猿說Python » python線程障礙對象Barrier