Python线程障碍对象Barrier原理详解


Posted in Python onDecember 02, 2019

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, 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代码实例
Feb 04 Python
Python 出现错误TypeError: ‘NoneType’ object is not iterable解决办法
Jan 12 Python
python中类变量与成员变量的使用注意点总结
Apr 29 Python
Python利用BeautifulSoup解析Html的方法示例
Jul 30 Python
Python在不同目录下导入模块的实现方法
Oct 27 Python
Python算法之图的遍历
Nov 16 Python
pip install urllib2不能安装的解决方法
Jun 12 Python
Python中join()函数多种操作代码实例
Jan 13 Python
详解Python修复遥感影像条带的两种方式
Feb 23 Python
Python xml、字典、json、类四种数据类型如何实现互相转换
May 27 Python
详解Python openpyxl库的基本应用
Feb 26 Python
使用pipenv管理python虚拟环境的全过程
Sep 25 Python
python 循环数据赋值实例
Dec 02 #Python
python创建n行m列数组示例
Dec 02 #Python
python 创建一维的0向量实例
Dec 02 #Python
python 初始化一个定长的数组实例
Dec 02 #Python
Python生态圈图像格式转换问题(推荐)
Dec 02 #Python
python 申请内存空间,用于创建多维数组的实例
Dec 02 #Python
python将数组n等分的实例
Dec 02 #Python
You might like
php用数组返回无限分类的列表数据的代码
2010/08/08 PHP
浅析PHP页面局部刷新功能的实现小结
2013/06/21 PHP
php array_merge_recursive 数组合并
2016/10/26 PHP
Javascript结合css实现网页换肤功能
2009/11/02 Javascript
Js 中debug方式
2010/02/07 Javascript
ExtJs默认的字体大小改变的几种方法(自己整理)
2013/04/18 Javascript
javascript实现textarea中tab键的缩排处理方法
2015/06/26 Javascript
sso跨域写cookie的一段js脚本(推荐)
2016/05/25 Javascript
Angularjs 实现一个幻灯片示例代码
2016/09/08 Javascript
基于jQuery制作小图标上下滑动特效
2017/01/18 Javascript
vue实现ToDoList简单实例
2017/02/07 Javascript
浅析Angular2子模块以及异步加载
2017/04/24 Javascript
JS实现的Unicode编码转换操作示例
2017/04/28 Javascript
Bootstrap datepicker日期选择器插件使用详解
2017/07/26 Javascript
图片加载完成再执行事件的实例
2017/11/16 Javascript
jQuery代码优化方法总结
2018/01/29 jQuery
基于 Immutable.js 实现撤销重做功能的实例代码
2018/03/01 Javascript
解决Vue 通过下表修改数组,页面不渲染的问题
2018/03/08 Javascript
vue 实现axios拦截、页面跳转和token 验证
2018/07/17 Javascript
微信小程序代码上传、审核发布小程序
2019/05/18 Javascript
浅析Angular 实现一个repeat指令的方法
2019/07/21 Javascript
JS实现提示效果弹出及延迟隐藏的功能
2019/08/26 Javascript
jQuery使用ajax传递json对象到服务端及contentType的用法示例
2020/03/12 jQuery
[00:10]DOTA2全国高校联赛 以DOTA2会友
2018/05/30 DOTA
[54:24]Optic vs TNC 2018国际邀请赛小组赛BO2 第二场
2018/08/18 DOTA
[02:58]魔廷新尊——痛苦女王至宝语音台词节选
2020/06/14 DOTA
python使用beautifulsoup从爱奇艺网抓取视频播放
2014/01/23 Python
python中urllib模块用法实例详解
2014/11/19 Python
基于Django的ModelForm组件(详解)
2017/12/07 Python
pygame实现贪吃蛇游戏(下)
2019/10/29 Python
PyTorch 导数应用的使用教程
2020/08/31 Python
英国最全面的橄榄球联盟门票网站:Live Rugby Tickets
2018/10/06 全球购物
Napapijri西班牙在线商店:夹克、外套、运动衫等
2020/11/05 全球购物
党支部对照检查材料
2014/08/25 职场文书
2014年节能工作总结
2014/12/18 职场文书
阿里云Nginx配置https实现域名访问项目(图文教程)
2021/03/31 Servers