Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

Vinllen Chen


To be a better coder

python异步通信之gevent.event.Event

  在Gevent Tutorial中所介绍的,我们可以用gevent.event.Event或者'gevent.event.AsyncResult'当作协程之间的事件,其中后者可以在唤醒别的协程时带上一个值。当然,我们还可以用gevent.event.Queuegevent.event.Groupgevent.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/


About the author

vinllen chen

Beijing, China

格物致知


Discussions

comments powered by Disqus