1. 程式人生 > 程式設計 >Python執行緒障礙物件Barrier原理詳解

Python執行緒障礙物件Barrier原理詳解

python執行緒Barrier俗稱障礙物件,也稱柵欄,也叫屏障。

一.執行緒障礙物件Barrier簡介

# 匯入執行緒模組
import threading
# 障礙物件barrier
barrier = threading.Barrier(parties,action=None,timeout=None)

parties — 執行緒計數器,記錄執行緒數量,也稱執行緒障礙數量;

action — 是一個可呼叫函式,當等待的執行緒到達了執行緒障礙數量parties,其中一個執行緒會首先呼叫action 對應函式,之後再執行執行緒自己內部的程式碼;

timeout — 預設的超時時間;

二.執行緒障礙物件Barrier原理


與之前介紹 互斥鎖Lock/事件Event/定時器Timer等不同,多執行緒Barrier會設定一個執行緒障礙數量parties,如果等待的執行緒數量沒有達到障礙數量parties,所有執行緒會處於阻塞狀態,當等待的執行緒到達了這個數量就會喚醒所有的等待執行緒。

可能說的有點抽象,以播放器為例子:首先一個執行緒做播放器初始化工作(載入本地檔案或者獲取播放地址),然後一個執行緒獲取視訊畫面,一個執行緒獲取視訊聲音,只有當初始化工作完畢,視訊畫面獲取完畢,視訊聲音獲取完畢,播放器才會開始播放,其中任意一個執行緒沒有完成,播放器會處於阻塞狀態直到三個任務都完成!

三.多執行緒障礙物件Barrier相關函式介紹

wait(timeout=None) — 阻塞並嘗試通過障礙,如果等待的執行緒數量大於或者等於執行緒障礙數量parties,則表示障礙通過,執行action 對應函式並執行執行緒內部程式碼,反之則繼續等待;如果wait(timeout=None) 等待超時,障礙將進入斷開狀態!如果線上程等待期間障礙斷開或重置,此方法會引發BrokenBarrierError錯誤,注意新增異常處理,演示程式碼檢視案例一;

reset() — 重置執行緒障礙數量,返回預設的空狀態,即當前阻塞的執行緒重新來過,如果線上程等待期間障礙斷開或重置,此方法會引發BrokenBarrierError錯誤,注意新增異常處理,演示程式碼檢視案例二;

四.執行緒障礙物件Barrier使用

1.案例一:常規使用

# !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錯誤,為了程式的健壯性,最好加上異常處理;

2.案例二:重置執行緒障礙數量reset()

# 匯入執行緒模組
import threading
 
def plyer_display():
  print('初始化通過完成,音視訊同步完成,可以開始播放....')
 
# 設定3個障礙物件
barrier = threading.Barrier(3,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",))
    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錯誤,為了程式的健壯性,最好加上異常處理;

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。