码迷,mamicode.com
首页 > 编程语言 > 详细

Python——eventlet.event

时间:2014-12-16 22:29:39      阅读:214      评论:0      收藏:0      [点我收藏+]

标签:style   blog   ar   io   color   os   使用   sp   for   

  该模块提供eventlet的事件支持,事件提供了跨 greenthread 的操作原语。

  同一个事件对象既可以发出事件也可以接收(等待)事件,不同的协程共享这一个事件对象,就为不同协程之间基于事件的同步提供了可能。

 

 class eventlet.event.Event 

  该类型抽象了以下事件:任意数量的协程可以等待其他一个协程发出的某一个事件。

  事件类似于一个只能容纳一个对象的队列,但是有以下两个方面的区别:

  1. 调用 send() 绝不会取消对当前greenthread的调度;

  2. send() 只能被调用一次,想要再发一遍这个事件,那么不好意思,重新创建一个Event对象吧。

  事件对于协程之间交流结果非常有用,同时也是 GreenThread.wait() 实现的基础。

  例如:

>>> from eventlet import event
>>> import eventlet
>>> evt = event.Event()
>>> def baz(b):
...     evt.send(b + 1)
...
>>> _ = eventlet.spawn_n(baz, 3)
>>> evt.wait()
4

  该类主要的方法有:

  ready()

  send(result=None, exc=None)

  reset()

  send_exception(*args)

  wait()

 

class eventlet.event.Event的方法

 

1.  ready() 

  判断一个Event对象有没有发出过事件,如果调用 wait() 会立即返回一个事件结果,那么此处就返回真值。

  该方法用来避免等待那些需要一段时间才会超时的事件。例如,你可以将一堆时间放到一个Python列表中,然后重复地遍历他们,这是就可以调用 ready() 直到其中的一个事件返回True,然后就可以立刻调用 wait() 来获取它了。

 

2.  send(result=None, exc=None) 

  用 result 唤醒等待者,然后立刻返回给父对象。

  例如:

>>> from eventlet import event
>>> import eventlet
>>> evt = event.Event()
>>> def waiter():
...     print(about to wait)
...     result = evt.wait()
...     print(waited for {0}.format(result))
>>> _ = eventlet.spawn(waiter)
>>> eventlet.sleep(0)
about to wait
>>> evt.send(a)
>>> eventlet.sleep(0)
waited for a

  一个event对象不能多次调用 send() 方法:

>>> evt.send(whoops)
Traceback (most recent call last):
...
AssertionError: Trying to re-send() an already-triggered event.

  可以在多次 send() 方法之间调用 reset() 来重用Event对象。注意使用 reset() 重置后调用 ready() 方法将返回假值,然后同一个Event对象又可以调用 send() 方法了。

 

3.  send_exception(*args) 

  作用类似于 send() 方法,只不过向等待者发送的是一个异常。

  该方法的参数和 raise 方法的参数完全相同,如果单个异常对象被传进来,它会在 wait() 方法被调用的时候重新抛出,生成一个新的堆栈轨迹。

  例如:

>>> from eventlet import event
>>> evt = event.Event()
>>> evt.send_exception(RuntimeError())
>>> evt.wait()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "eventlet/event.py", line 120, in wait
    current.throw(*self._exc)
RuntimeError

  如果需要完整地保留堆栈轨迹,必须传入整个 sys.exc_info() 元组。

>>> import sys
>>> evt = event.Event()
>>> try:
...     raise RuntimeError()
... except RuntimeError:
...     evt.send_exception(*sys.exc_info())
...
>>> evt.wait()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "eventlet/event.py", line 120, in wait
    current.throw(*self._exc)
  File "<stdin>", line 2, in <module>
RuntimeError

  此时会在Event对象内部存储一个 traceback 对象,这可能会导致循环引用。详见 sys.exc_info() 的文档。

 

4.  wait() 

  等待直到另一个协程调用 send() 。返回其他协程传递给 send() 方法的值。

  例如:

>>> from eventlet import event
>>> import eventlet
>>> evt = event.Event()
>>> def wait_on():
...    retval = evt.wait()
...    print("waited for {0}".format(retval))
>>> _ = eventlet.spawn(wait_on)
>>> evt.send(result)
>>> eventlet.sleep(0)
waited for result

  最后的一句如果改为调用 wait() 方法的话,只要已经有一个协程已经发出过事件,此处会立即返回结果:

>>> evt.wait()
result

   *评:

  一个Event对象在 send() 以后,除非 reset() ,否则多次 wait() 也不会删除 send() 时发出的值,再结合如果不 reset()send() 只能调用一次,不难理解为什么这里说是“多个协程等待其他一个协程发出某一个事件”了。

Python——eventlet.event

标签:style   blog   ar   io   color   os   使用   sp   for   

原文地址:http://www.cnblogs.com/Security-Darren/p/4168116.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!