Python線程障礙對象Barrier原理詳解
python線程Barrier俗稱障礙對象,也稱柵欄,也叫屏障。
一.線程障礙對象Barrier簡介
# 導入線程模塊 import threading # 障礙對象barrier barrier = threading.Barrier(parties, action=None, timeout=None)
parties — 線程計數(shù)器,記錄線程數(shù)量,也稱線程障礙數(shù)量;
action — 是一個可調用函數(shù),當?shù)却木€程到達了線程障礙數(shù)量parties,其中一個線程會首先調用action 對應函數(shù),之后再執(zhí)行線程自己內(nèi)部的代碼;
timeout — 默認的超時時間;
二.線程障礙對象Barrier原理
與之前介紹 互斥鎖Lock/事件Event/定時器Timer等不同,多線程Barrier會設置一個線程障礙數(shù)量parties,如果等待的線程數(shù)量沒有達到障礙數(shù)量parties,所有線程會處于阻塞狀態(tài),當?shù)却木€程到達了這個數(shù)量就會喚醒所有的等待線程。
可能說的有點抽象,以播放器為例子:首先一個線程做播放器初始化工作(加載本地文件或者獲取播放地址),然后一個線程獲取視頻畫面,一個線程獲取視頻聲音,只有當初始化工作完畢,視頻畫面獲取完畢,視頻聲音獲取完畢,播放器才會開始播放,其中任意一個線程沒有完成,播放器會處于阻塞狀態(tài)直到三個任務都完成!
三.多線程障礙對象Barrier相關函數(shù)介紹
wait(timeout=None) — 阻塞并嘗試通過障礙,如果等待的線程數(shù)量大于或者等于線程障礙數(shù)量parties,則表示障礙通過,執(zhí)行action 對應函數(shù)并執(zhí)行線程內(nèi)部代碼,反之則繼續(xù)等待;如果wait(timeout=None) 等待超時,障礙將進入斷開狀態(tài)!如果在線程等待期間障礙斷開或重置,此方法會引發(fā)BrokenBarrierError錯誤,注意添加異常處理,演示代碼查看案例一;
reset() — 重置線程障礙數(shù)量,返回默認的空狀態(tài),即當前阻塞的線程重新來過,如果在線程等待期間障礙斷開或重置,此方法會引發(fā)BrokenBarrierError錯誤,注意添加異常處理,演示代碼查看案例二;
四.線程障礙對象Barrier使用
1.案例一:常規(guī)使用
# !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秒內(nèi),沒有達到障礙線程數(shù)量, # 會進入斷開狀態(tài),引發(fā)BrokenBarrierError錯誤 barrier.wait(2) except Exception as e: # 斷開狀態(tài),引發(fā)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)等待超時,會進入斷開狀態(tài),引發(fā)BrokenBarrierError錯誤,為了程序的健壯性,最好加上異常處理;
2.案例二:重置線程障礙數(shù)量reset()
# 導入線程模塊 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秒內(nèi),沒有達到障礙線程數(shù)量, # 會進入斷開狀態(tài),引發(fā)BrokenBarrierError錯誤 barrier.wait(2) except Exception as e: # 斷開狀態(tài),引發(fā)BrokenBarrierError錯誤 # print("斷開狀態(tài)... ") 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: # 重置狀態(tài) 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)等待超時,會進入斷開狀態(tài),引發(fā)BrokenBarrierError錯誤,為了程序的健壯性,最好加上異常處理;
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
- Java并發(fā)編程:CountDownLatch與CyclicBarrier和Semaphore的實例詳解
- Java并發(fā)編程(CyclicBarrier)實例詳解
- Java并發(fā)編程之柵欄(CyclicBarrier)實例介紹
- Java中CyclicBarrier的用法分析
- python面向對象多線程爬蟲爬取搜狐頁面的實例代碼
- Python使用面向對象方式創(chuàng)建線程實現(xiàn)12306售票系統(tǒng)
- python 實現(xiàn)多線程下載視頻的代碼
- python 實現(xiàn)多線程下載m3u8格式視頻并使用fmmpeg合并
- python子線程退出及線程退出控制的代碼
相關文章
PyCharm運行Python代碼時出現(xiàn)"未找到模塊"錯誤解決步驟
在使用python的過程中經(jīng)常會遇到一個問題,就是叫什么名字的模塊未發(fā)現(xiàn),下面這篇文章主要給大家介紹了關于PyCharm運行Python代碼時出現(xiàn)"未找到模塊"錯誤的解決步驟,需要的朋友可以參考下2023-11-11sklearn-SVC實現(xiàn)與類參數(shù)詳解
今天小編就為大家分享一篇sklearn-SVC實現(xiàn)與類參數(shù)詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-12-12