并发编程四(3) 线程同步 - Event-信号传递
Event-信号传递
threading.Event源码的解释是这样的,
class Event:
"""Class implementing event objects.
Events manage a flag that can be set to true with the set() method and reset
to false with the clear() method. The wait() method blocks until the flag is
true. The flag is initially false.
"""
我用大白话解释一下大致意思:event是一个内部对象,他管理着一个信号,且这个信号flag一开始是false,
set()
方法可以把flag设置成true,这时候程序继续往下执行,
clear()
方法会把flag设置成false,
wait(timeout)
方法会一直阻塞,直到收到那个为true的内部信号或者等待时间=timeout,结束等待,继续执行后面的代码
然后我们再来看例子,就会好理解一点
from threading import Thread
import threading
import time
def wait_for_event(e):
"""Wait for the event to be set before doing anything"""
print('wait_for_event: starting')
e.wait() # 等待收到能执行信号,如果一直未收到将一直阻塞
print('wait_for_event: e.is_set()->', e.is_set())
def wait_for_event_timeout(e,t):
"""Wait t seconds and then timeout"""
print('wait_for_event_timeout: starting')
e.wait(t)# 等待t秒超时,此时Event的状态仍为未设置,继续执行
print('wait_for_event_timeout: e.is_set()->', e.is_set())
e.set()# 初始内部标志为真 想把e内部的变量从Faslse改为True,则使用e.set()
if __name__ == '__main__': # main是主线程
e = threading.Event() #生成一个类实例
print("begin,e.is_set()", e.is_set())
w1 = Thread(name='block', target=wait_for_event, args=(e,))
w1.start()
#可将2改为5,看看执行结果
w2 = Thread(name='nonblock', target=wait_for_event_timeout, args=(e,2))
w2.start()
print('main: waiting before calling Event.set()')
time.sleep(3)
# e.set() #可注释此句话看效果
#这里如果加入w1.join(),那就会等w1线程执行完毕,再打印下面这句话
#w1.join()
print('main: event is set')
注意:
没有线程调用set()方法,且wait也没有设置超时时间,wait最终总是会返回true,这一点很重要,不然你难以理解为什么没有线程把flag设置为true,但是wait后面的代码最终还是会执行。我为什么会知道?可以看源码
def wait(self, timeout=None):
"""Block until the internal flag is true.
If the internal flag is true on entry, return immediately. Otherwise,
block until another thread calls set() to set the flag to true, or until
the optional timeout occurs.
When the timeout argument is present and not None, it should be a
floating point number specifying a timeout for the operation in seconds
(or fractions thereof).
This method returns the internal flag on exit, so it will always return
True except if a timeout is given and the operation times out.
"""
with self._cond:
signaled = self._flag
if not signaled:
signaled = self._cond.wait(timeout)
return signaled
更多学习笔记移步
https://www.cnblogs.com/kknote