• python线程障碍对象Barrier(34)


       

        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错误,为了程序的健壮性,最好加上异常处理;

     

    猜你喜欢:

        1.python多线程创建和参数传递

        2.python多线程条件变量Condition

        3.python多线程互斥锁Lock

        4.python多线程事件Event

        5.python多线程定时器Timer

     

        转载请注明:猿说Python » python线程障碍对象Barrier

     

    技术交流、商务合作请直接联系博主
    扫码或搜索:猿说python
    python教程公众号
    猿说python
    微信公众号 扫一扫关注
  • 相关阅读:
    Windows下快速搭建安卓开发环境android-studio
    使用Android Studio搭建Android集成开发环境
    手动安装配置Android Studio
    android studio 各种问题 应该能帮助到你们
    如何清除XP的网络共享密码
    一个语言的“入流”,而是和这种语言进入某一子行业的契机有关
    必须冷静、必须听话,赶紧走
    QWidget继承自QPaintDevice,这样就可以直接把QWidget传入QPainter的构造函数,比如QPainter(mylabel),然后设置QWidget的长宽后直接进行作画了
    ActiveMQ
    开源word操作组件DocX的记录
  • 原文地址:https://www.cnblogs.com/shuopython/p/11965374.html
Copyright © 2020-2023  润新知