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之dict()的操作方法
Sep 24 Python
Python的Django框架中设置日期和字段可选的方法
Jul 17 Python
Python随机读取文件实现实例
May 25 Python
运行django项目指定IP和端口的方法
May 14 Python
python 字典 按key值大小 倒序取值的实例
Jul 06 Python
Django实现表单验证
Sep 08 Python
使用python进行拆分大文件的方法
Dec 10 Python
使用Python实现分别输出每个数组
Dec 06 Python
Pygame的程序开始示例代码
May 07 Python
Python实现电视里的5毛特效实例代码详解
May 15 Python
Python读取xlsx数据生成图标代码实例
Aug 12 Python
如何用Python和JS实现的Web SSH工具
Feb 23 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
phpmyadmin 访问被拒绝的真实原因
2009/06/15 PHP
浅析php中抽象类和接口的概念以及区别
2013/06/27 PHP
PHP获取MAC地址的具体实例
2013/12/13 PHP
php传值赋值和传地址赋值用法实例分析
2015/06/20 PHP
thinkPHP5分页功能实现方法分析
2017/10/25 PHP
JS类的封装及实现代码
2009/12/02 Javascript
javascript 用记忆函数快速计算递归函数
2010/03/15 Javascript
JavaScript 原型继承
2011/12/26 Javascript
调用HttpHanlder的几种返回方式小结
2013/12/20 Javascript
js 触发select onchange事件代码
2014/03/20 Javascript
jQuery中Ajax的get、post等方法详解
2015/01/20 Javascript
JS实现数组去重,显示重复元素及个数的方法示例
2019/01/21 Javascript
使用vscode快速建立vue模板过程详解
2019/10/10 Javascript
微信小程序图片右边加两行文字的代码
2020/04/23 Javascript
实例讲解JavaScript 计时事件
2020/07/04 Javascript
nodejs处理tcp连接的核心流程
2021/02/26 NodeJs
python文件和目录操作方法大全(含实例)
2014/03/12 Python
研究Python的ORM框架中的SQLAlchemy库的映射关系
2015/04/25 Python
详解Python 模拟实现生产者消费者模式的实例
2017/08/10 Python
scrapy spider的几种爬取方式实例代码
2018/01/25 Python
python3如何将docx转换成pdf文件
2018/03/23 Python
Python 统计字数的思路详解
2018/05/08 Python
python实现停车管理系统
2018/11/30 Python
python3 字符串/列表/元组(str/list/tuple)相互转换方法及join()函数的使用
2019/04/03 Python
python 将字符串中的数字相加求和的实现
2019/07/18 Python
django中上传图片分页三级联动效果的实现代码
2019/08/30 Python
Python+Appium实现自动化清理微信僵尸好友的方法
2021/02/04 Python
AmazeUI 缩略图的实现示例
2020/08/18 HTML / CSS
Vans澳大利亚官网:购买鞋子、服装及配件
2019/09/05 全球购物
美国床垫连锁店:Mattress Firm
2021/02/13 全球购物
main 主函数执行完毕后,是否可能会再执行一段代码,给出说明
2012/12/05 面试题
倡议书格式范文
2014/04/14 职场文书
2015年医院工作总结范文
2015/04/09 职场文书
煤矿隐患排查制度
2015/08/05 职场文书
小数乘法教学反思
2016/02/22 职场文书
python_tkinter弹出对话框创建
2022/03/20 Python