Python——eventlet.event

  该模块提供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() 只能调用一次,不难理解为什么这里说是“多个协程等待其他一个协程发出某一个事件”了。

时间: 2024-10-26 04:56:17

Python——eventlet.event的相关文章

Python——eventlet.hubs

Hub构成了 Eventlet 的事件循环,它分发 I/O 事件.调度 greenthread.Hub的存在使得协程被提升为 greenthreads. Eventlet 有多种hub的实现,所以在使用之前应该选择最适合自己系统的实现: epolls 要求 Python 2.6 或 python-epoll 包,同时只支持 Linux.这是最快的纯Python hub. poll 所有支持它的平台均可. selects 哪都能用. pyevent 基于libevent的后端,最快!默认是不被支持

Python——eventlet

eventlet语境下的“绿色线程”普通线程之间的区别: 1. 绿色线程几乎没有开销,不用像保留普通线程一样保留“绿色线程”,每一个网络连接对应至少一个“绿色线程”: 2. 绿色线程需要人为的设置使其互相让渡CPU控制权,而不是抢占.绿色线程既能够共享数据结构,又不需要显式的互斥控制,因为只有当一个绿色线程让出了控制权后其他的绿色线程才能访问彼此共享的数据结构. 下图是eventlet中协程.hub.线程.进程之间的关系: ____________________________________

Python——eventlet.backdoor

eventlet.backdoor 是正在运行中的进程内的 Pyhon 交互解释器. 该模块便于检测一个长期运行进程的运行状态,提供了一种可以不阻塞应用正常操作的 Pyhon 交互解释器,从而极大地方便了调试.性能调优或仅仅是了解事情是怎么运转的. 在应用中孵化一个协程,这个协程运行一个 backdoor_server ,这个 backdoor_server 中有一个处于监听状态的套接字: eventlet.spawn(backdoor.backdoor_server, eventlet.lis

Python线程event

python线程的事件用于主线程控制其他线程的执行,事件主要提供了三个方法wait.clear.set 事件处理的机制:全局定义了一个“Flag”,如果“Flag”值为 False,那么当程序执行 event.wait 方法时就会阻塞,如果“Flag”值为True,那么event.wait 方法时便不再阻塞. clear:将“Flag”设置为False set:将“Flag”设置为True 用 threading.Event 实现线程间通信使用threading.Event可以使一个线程等待其他

Python——eventlet.wsgi

eventlet 的 wsgi 模块提供了一种启动事件驱动的WSGI服务器的简洁手段,可以将其作为某个应用的嵌入web服务器,或作为成熟的web服务器,一个这样的web服务器的例子就是 Spawning. 目录 一.Eventlet 的 WSGI 服务器 1. eventlet.wsgi.server() 2. eventlet.wsgi.format_data_time() 二.SSL 三.Post hooks 四.“100 continue”响应头 一.Eventlet 的 WSGI ser

Python——eventlet.greenpool

该模块提供对 greenthread 池的支持. greenthread 池提供了一定数量的备用 greenthread ,有效限制了孵化 greenthread 过多导致的内存不足,当池子中没有足够的空闲 greenthread 时,孵化过程被暂停,只有当先前工作中的 greenthread 完成当前工作,才能为下一个任务做孵化准备. 本模块包括两个类: 1. eventlet.greenpool.GreenPool 2. eventlet.greenpool.GreenPile 一. cla

python jQuery event 取不到更改的方案(暂时)

<!--<script type="text/javascript"> $("a[id^='uid']").click(OnClick()); function OnClick(event) { //alert(event); var id=event.target.id.split('_')[1]; location.href=" Info?id="+id; }</script>--> 上面的代码发生问题,后

Python使用Event线程间通信

使用threading.Event可以使一个线程等待其他线程的通知, 把这个Event传递到线程对象中,Event默认内置了一个标志,初始值为False.一旦该线程通过wait()方法进入等待状态,直到另一个线程调用该Event的set()方法将内置标志设置为True时,该Event会通知所有等待状态的线程恢复运行. import threading import time class MyThread(threading.Thread): def __init__(self, signal):

python之event【事件】

# 线程之间用于交互的一个对象,这个event是一个内部的标签,线程可以等待这个标签的状态 #举个例子,比如红绿灯是一个线程,三辆汽车是3个线程,如果为红灯,则三个汽车的线程必须 #要停止,如果是绿灯,则三个汽车的线程就可以跑起来 import threading #创建一个事件 event = threading.Event() #如果标签没有设置,则线程会一直等待,直到标签的状态被设置,如果设定了标签,则这里的 #wait就不阻塞了,该动作什么都不做,如果没有设置,则该wait这里就一直阻塞