Python 多线程 -- 事件通知 threading.Event
有时候,我们线程 A 和 B 运行中,需要等待某个条件 (某件事情发生),才能继续运行下面的代码。事件还没发生前,线程阻塞住,直到事件的发生。
Python 中 threading.Event 就可以实现线程间的事件通知。
threading.Event
- 等待事件者,调用 wait,等待事件
- 通知事件者,调用 set,通知事件
- wait 可以接受到参数,等待多少秒,默认是一直阻塞等待下去
简单示例
import threading
import time,random
def say(e):
time.sleep(random.random())
print '准备说话中。。。。'
e.wait()
time.sleep(random.random())
print('%s->可以开始说话了' % (threading.currentThread().name))
e = threading.Event()
t1 = threading.Thread(target=say, args=(e,), name='线程1')
t2 = threading.Thread(target=say, args=(e,), name='线程2')
t1.start()
t2.start()
time.sleep(10)
e.set()
结果:
准备说话中。。。。
准备说话中。。。。
线程1->可以开始说话了
线程2->可以开始说话了
示例二
创建个继承 threading.Thread 的类 Player。
Player 类 run 方法中,要等待上一个通知操作, 操作了后,通知下一家操作。
e_pre.wait()[等待上一家通知] –> 操作 –> e_self.set()[通知下一家操作]。 每个操作三次。
import threading,time
class Player(threading.Thread):
def __init__(self, name , e_pre, e_self):
threading.Thread.__init__(self)
self.name = name
self.e_pre = e_pre
self.e_self = e_self
self.count = 0
def run(self):
while self.count < 3:
self.count += 1
time.sleep(2.1)
self.e_pre.wait()
print('%s 第%d次操作===>' % (self.name, self.count))
time.sleep(1)
self.e_self.set()
time.sleep(0.1)
print('%s Done!' % self.name)
创建 3 个 Player 实例,a、b、c;
3 个 threading.Event 实例,a_event, b_event, c_event。
操作顺序: a -> b -> c。
通知顺序:
c_event.set(), 通知 a 可以操作了。a_event.set() 就可以通知 b 操作了,b_evnet.set(), 通知 c 可以操作了。
# a,b,c用户,分别对于三个event,负责通知下一个用户操作
a_event = threading.Event()
b_event = threading.Event()
c_event = threading.Event()
# 操作顺序: a -> b -> c
# 通知操作: c_event -> a ; a_event -> b; b_event ->c
a = Player('A', c_event, a_event)
b = Player('B', a_event, b_event)
c = Player('C', b_event, c_event)
for i in [a, b, c]:
i.start()
# 延时要配置好,要不,输出顺序会乱
time.sleep(3)
# 最开始是由a出牌
# b_event.set()
c_event.set()
for i in [a, b, c]:
i.join()
print('-'*15)
输出结果:
A 第1次操作===>
B 第1次操作===>
C 第1次操作===>
A 第2次操作===>
B 第2次操作===>
C 第2次操作===>
A 第3次操作===>
B 第3次操作===>
A Done!
C 第3次操作===>
B Done!
C Done!
---------------
注意: time.sleep 参数的配置要合理 (否则输出结果顺序不对),本示例只是简单演示。