Python Event对象

Python Event对象教程

Python 的 Event 对象用于 线程 间通信,即程序中的某一个线程需要通过判断另一个线程的状态来确定自己下一步的操作,这时就需要使用 event 对象。

Event 对象包含一个可由线程设置的信号标志,它允许线程等待某些事件的发生。在初始情况下,Event 对象中的信号标志被设置为 False。如果有线程等待一个 Event 对象, 而这个 Event 对象的标志为假,那么这个线程将会被一直阻塞直至该标志为真。

一个线程如果将一个 Event 对象的信号标志设置为真,它将唤醒所有等待这个 Event 对象的线程。如果一个线程等待一个已经被设置为真的 Event 对象,那么它将忽略这个事件, 继续执行。

Event 的几种方法

函数 说明
event.isSet() 返回 event 的状态值
event.wait() 如果 event.isSet() == False 将阻塞线程
event.set() 设置 event 的状态值为 True,所有阻塞池的线程激活进入就绪状态, 等待操作系统调度
event.clear() 恢复 event 的状态值为 False

案例

使用 Python Event 实现多线程同步

使用 Python Event 实现子线程与主线程的同步

import threading import time event = threading.Event() def connect_server(): print('wait for server to start...') event.wait() #括号里可以带数字执行,数字表示等待的秒数,不带数字表示一直阻塞状态 print('connect to server successful') if __name__ == '__main__': print("嗨客网(www.haicoder.net)") t = threading.Thread(target=connect_server, args=()) #子线程执行foo函数 t.start() time.sleep(3) print('start server successful') event.set() #默认为False,set一次表示True,所以子线程里的connect_server函数解除阻塞状态继续执行

程序运行后,控制台输出如下:

16 python event.png

我们首先使用 threading.Event() 创建了一个 Event 对象的实例,接着定义了一个线程处理函数 connect_server,在 main 函数中,我们首先创建了一个线程 t,其线程处理函数就是 connect_server。

接着,我们使用 sleep 等待 3 秒钟,线程处理函数运行后因为 event.wait() 的存在,所以会一直等待你,在主线程 sleep 3秒结束后,主线程的 event.set() 触发,此时子线程 t 的 event.wait() 不再阻塞。

所以,我们看到,程序运行后,子线程使用 event.wait() 等待主线程,主线程运行 3 秒后使用 event.set() 通知子线程,子线程不再阻塞,继续运行,即我们使用 Event 实现了主线程与子线程的同步。

使用 Python Event 实现多线程同步

使用 Python Event 实现子线程与子线程的同步

import threading import time event = threading.Event() def connect_server(): print('wait for server to start...') event.wait() #括号里可以带数字执行,数字表示等待的秒数,不带数字表示一直阻塞状态 print('connect to server successful') def server_start(): time.sleep(3) print('start server successful') event.set() #默认为False,set一次表示True,所以子线程里的foo函数解除阻塞状态继续执行 if __name__ == '__main__': print("嗨客网(www.haicoder.net)") t = threading.Thread(target=connect_server, args=()) #子线程执行connect_server函数 t.start() t2 = threading.Thread(target=server_start,args=()) #子线程执行server_start函数 t2.start()

程序运行后,控制台输出如下:

17 python event.png

我们定义了两个线程,即线程 t 与线程 t2,线程 t 模拟的是连接服务器的操作,线程 t2 模拟的是运行服务器的操作。

在线程 t 的线程处理函数 connect_server 中,我们使用了 event.wait() 阻塞等待服务器的开启,在线程 t2 的线程处理函数 server_start 中,我们使用了 event.set() 通知了线程 t 服务器已经启动。

所以,在线程 t2 使用 event.set() 通知线程 t 服务器已经启动后,线程 t 的阻塞立刻被终止,线程 t 继续运行。

使用 Python Event 实现多线程同步

使用 Python Event 实现子线程与子线程的同步

import threading import time event = threading.Event() def light(): print('红灯正亮着') time.sleep(3) event.set() # 模拟绿灯亮 def car(name): print('车%s正在等绿灯' % name) event.wait() # 模拟等绿灯的操作,此时event为False,直到event.set()将其值设置为True,才会继续运行 print('车%s通行' % name) if __name__ == '__main__': print("嗨客网(www.haicoder.net)") # 红绿灯 t1 = threading.Thread(target=light) t1.start() # 车 for i in range(3): t = threading.Thread(target=car, args=(i,)) t.start()

程序运行后,控制台输出如下:

18 python event.png

首先,我们定义了一个模拟红路灯的线程 t1 ,其线程处理函数为 light,接着,我们使用 for 循环 连续创建了三个线程,用来模拟汽车等待红绿灯通行的场景。

在线程 t1 的线程处理函数 light 中,我们使用了 event.set() 模拟绿灯亮起,在线程 t 的线程处理函数 car 中,我们使用了 event.wait() 模拟等待绿灯的场景。

最终运行,我们看到,当线程 light 使用 event.set() 模拟绿灯亮起时,线程 car 的 event.wait() 阻塞被取消,所有的 car 线程都可以继续运行。

Python Event对象教程总结

Python 的 Event 对象用于线程间通信,即程序中的某一个线程需要通过判断另一个线程的状态来确定自己下一步的操作,这时就需要使用 event 对象。

一个线程如果将一个 Event 对象的信号标志设置为真,它将唤醒所有等待这个 Event 对象的线程。如果一个线程等待一个已经被设置为真的 Event 对象,那么它将忽略这个事件, 继续执行。