• python线程的同步事件Event


    Event对象:

    用于线程间的通信,某个线程需要根据其他线程的状态来判断自己的下一步操作。

    Event内部定义了一个全局变量:_flag,默认为False。 当_flag = False时,会阻塞当前线程的执行;_flag = True时,当前线程会继续执行。

    Event内部还定义了如下方法来操纵标志位:

    • set() ——将_flag(标志位)设置为True;
    • clear()——将_flag设置为False;
    • is_set()——返回当前_flag的状态。等同于isSet()。
    • wait()——阻塞当前线程的执行,直到_flag被设置为True。只有当_flag = False时,调用wait()才会阻塞当前线程的运行,此时wait()方法相当于pass(什么也不做)。

    示例1:主线程控制子线程的执行。

     1 import threading, time
     2 
     3 event = threading.Event()
     4 
     5 def foo():
     6     print("wait server... at ", time.ctime()) # 开启子线程t时打印这句话
     7     event.wait() # 阻塞子线程的执行,此时event中的标志位为False
     8     print("connect to server... at ", time.ctime())
     9 
    10 
    11 t = threading.Thread(target=foo,args=())
    12 
    13 t.start() # 开启一个子线程
    14 time.sleep(3) # 主线程休眠3秒
    15 print("start server successfully... at ", time.ctime()) # 在foo函数中的event.wait()后打印这句话,此时子线程被阻塞
    16 time.sleep(3) # 主线程继续休眠3秒
    17 event.set() # 将event中的标志位设置为True,foo函数中的最后一句话就被打印了。
    18 print(event.is_set())

     打印结果如下:

    wait server... at  Sun Mar 24 11:25:51 2019
    start server successfully... at  Sun Mar 24 11:25:54 2019
    connect to server... at  Sun Mar 24 11:25:57 2019

    整个程序的流程如下所示:

     示例2:子线程之间传递evnet

     1 import threading, time
     2 
     3 class Boss(threading.Thread):
     4     
     5     def run(self):
     6 
     7         print("BOSS: 今晚加班到22:00")
     8         print(event.is_set()) # _flag = False
     9 
    10         event.set() # 将_flag设置为True,Worker线程往下执行
    11         time.sleep(5)
    12 
    13         print("BOSS: 22:00了,可以下班了 at ", time.ctime())
    14         print(event.is_set())
    15 
    16         event.set() # 宣布下班后,将_flag设置为True,Worker线程继续执行
    17 
    18 
    19 class Worker(threading.Thread):
    20     def run(self):
    21         event.wait() # 此时Worker线程被阻塞,等待Boss线程先运行
    22         print("Worker: 命苦啊。。。at ", time.ctime())
    23 
    24         time.sleep(1)
    25 
    26         event.clear() # 将_flag设置为False
    27         event.wait() # 阻塞Worker线程运行,等待老板下班命令
    28 
    29         print("Worker: oh yeah!")
    30 
    31 
    32 if __name__ == '__main__':
    33     
    34     event = threading.Event()
    35 
    36     threads = []
    37 
    38     for i in range(5):
    39         threads.append(Worker())
    40 
    41     threads.append(Boss())
    42 
    43     for t in threads:
    44         t.start()
    45 
    46     # 阻塞主线程,让子线程先执行完毕
    47     for t in threads:
    48         t.join()

    打印结果如下所示:

    BOSS: 今晚加班到22:00
    False
    Worker: 命苦啊。。。at  Sun Mar 24 16:56:53 2019
    Worker: 命苦啊。。。at  Sun Mar 24 16:56:53 2019
    Worker: 命苦啊。。。at  Sun Mar 24 16:56:53 2019
    Worker: 命苦啊。。。at  Sun Mar 24 16:56:53 2019
    Worker: 命苦啊。。。at  Sun Mar 24 16:56:53 2019
    BOSS: 22:00了,可以下班了 at  Sun Mar 24 16:56:58 2019
    False
    Worker: oh yeah!
    Worker: oh yeah!
    Worker: oh yeah!
    Worker: oh yeah!
    Worker: oh yeah!
    
    ***Repl Closed***

    线程的执行过程与event传递如图所示:

    由此看见,Event对象作为一个标志位,让一个线程便于控制另一个或另一些线程的执行,而控制方式就是修改标志位的布尔值。

    代码参考:

    https://www.cnblogs.com/lidagen/p/7252247.html

    http://www.cnblogs.com/yuanchenqi/articles/6248025.html

  • 相关阅读:
    业务场景和业务用例场景的区别(作者:Arthur网友)
    svn 安装
    PHP has encountered an Access Violation at
    邀请大象一书的读者和广大网友写关于分析设计、建模方面的自愿者文章
    手机网页 复制信息方法 免费短信
    delphi Inno Setup 制作安装程序
    Special Folders
    Windows mobile上获取输入光标位置
    加壳程序无法准确读输入表的解决办法
    C++ PostMessage 模拟键盘鼠标
  • 原文地址:https://www.cnblogs.com/guyexiangyun/p/10587074.html
Copyright © 2020-2023  润新知