在Gevent Tutorial中所介绍的,我们可以用gevent.event.Event
或者'gevent.event.AsyncResult'当作协程之间的事件,其中后者可以在唤醒别的协程时带上一个值。当然,我们还可以用gevent.event.Queue
, gevent.event.Group
,gevent.coros import BoundedSemaphore
等等用作协程间通信的工具。今天我所说的是gevent.event.Event
。
正如文档中所给出的最简单的例子:
import gevent
from gevent.event import Event
'''
Illustrates the use of events
'''
evt = Event()
def setter():
'''After 3 seconds, wake all threads waiting on the value of evt'''
print('A: Hey wait for me, I have to do something')
gevent.sleep(3)
print("Ok, I'm done")
evt.set()
def waiter():
'''After 3 seconds the get call will unblock'''
print("I'll wait for you")
evt.wait() # blocking
print("It's about time")
def main():
gevent.joinall([
gevent.spawn(setter),
gevent.spawn(waiter),
gevent.spawn(waiter),
gevent.spawn(waiter),
gevent.spawn(waiter),
gevent.spawn(waiter)
])
if __name__ == '__main__': main()
一个协程可以通过evt.wait()
来进行阻塞以便等待其他协程发来异步信号,在setter()
函数中我们可以通过evt.set()
来触发其他协程。这个例子比较简单,evt.set()
会永远生效,也就是说,之后如果别的协程再调用evt.wait()
将会直接返回,这时候我们可以调用evt.clear()
来清除已经生效的set()
。例子如下:
import gevent
from gevent.event import Event
evt = Event()
def setter():
print('In setter')
gevent.sleep(3)
print("After first sleep")
evt.set() #first set
print 'second sleep'
gevent.sleep(3)
evt.set() #second set
print 'end of setter'
def waiter():
print("in waiter")
evt.wait() #first wait
print 'after first wait'
evt.wait() #second wait
print 'end of waiter'
gevent.joinall([
gevent.spawn(setter),
gevent.spawn(waiter),
])
在这个代码中,我的目的是希望第一个evt.set()
触发第一个evt.wait()
,第二个evt.set()
触发第二个evt.wait()
,然而这么设计没办法直接达到目的,第二个将会直接返回。正确的修改如下:
def setter():
print('In setter')
gevent.sleep(3)
print("After first sleep")
evt.set() #first set
### now clear evt
evt.clear()
###
print 'second sleep'
gevent.sleep(3)
evt.set() #second set
print 'end of setter'
evt.set()
不会直接导致协程的切换,但会置信号量为真,等待本协程切换后,evt.wait()
就可以往下继续运行。
参考:
http://stackoverflow.com/questions/32503964/python-gevent-event-event/32504340#32504340
说明:
装载请注明出处:http://vinllen.com/python-yi-bu-tong-xin-zhi-gevent-event-event/