事件 Event是另一种python多线程同步技术, 本文将使用python语言对这种技术进行讲解, 想象这样一个场景,你启动了多个线程,这些线程都要去访问一个资源,但是,这里有一个小小的问题,即将被访问的资源还没有准备好接受访问,那么此时,多个线程去访问,必然得到不响应,你还得处理这种得不到响应的情况
借助Event,可以灵活的协调线程间的操作,它提供了下面几个方法
将事件内部标识设置为True,Event对象最初创建时,内部标识默认是False
当在线程中调用wait时,如果事件内部标识为False,则会阻塞,直到set方法被调用,将内部标识设置为True
将内部标识重新设置为False
如果内部标识是True,则返回True,反之,返回False
想象这样一个场景,你启动了多个线程,这些线程都要去访问一个资源,但是,这里有一个小小的问题,即将被访问的资源还没有准备好接受访问,那么此时,多个线程去访问,必然得到不响应,你还得处理这种得不到响应的情况。
这样的场景下,能否先在主线程里去做试探,确定资源可以访问以后,再让已经启动了的多线程去访问呢?让我们考虑一下如何用Event来处理这样的问题
以下为示例代码
import threading
from threading import Event
def worker(event_obj, i):
print('{i}号线程等待事件信号'.format(i=i))
event_obj.wait()
print('{i}号线程收到事件信号'.format(i=i))
event = Event()
for i in range(5):
t = threading.Thread(target=worker, args=(event, i))
t.start()
print('确认资源可用')
event.set()
一个线程依次打印1 3 5 ,一个线程依次打印 2 4 6,使用事件做消息同步,使得两个线程启动后,打印出1 2 3 4 5 6, 别看要求很简单,但实现起来却是有难度的,每个线程输出不同的数列,但整体上看却要求有序。
针对这样的线程同步要求,可以创建两个Event对象,两个线程互相触发另一个线程的Event对象
import threading
from threading import Event
def print_a(e1, e2):
for item in [1, 3, 5]:
e1.wait()
print(item)
e1.clear()
e2.set()
def print_b(e1, e2):
for item in [2, 4, 6]:
e1.wait()
print(item)
e1.clear()
e2.set()
e1, e2 = Event(), Event()
t1 = threading.Thread(target=print_a, args=(e1, e2))
t2 = threading.Thread(target=print_b, args=(e2, e1))
t1.start()
t2.start()
e1.set()
QQ交流群: 211426309