该模块提供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

该类主要的方法有:

  1. ready()

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

  3. reset()

  4. send_exception(*args)

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

  自己写了一个小剧本,放在这里解释这个模块:

import time
import eventlet
from eventlet import event
from eventlet import greenthread evt = event.Event() def Joker():
i = 0
while i < 3:
print "Joker: Can anybody get me?"
i += 1
time.sleep(1) print evt.wait()
print "Fighting."
time.sleep(3)
return "Joker: Sorry, you got missed." def Batman():
evt.send("Bat man: I'm coming for you!")
return "Bat man: I'm back, and your day is coming soon!" #Joker()
gt1 = greenthread.spawn(Joker)
gt2 = greenthread.spawn_after(5, Batman) print gt1.wait() time.sleep(1)
print gt2.wait() time.sleep(2)
print "To be continued."

  

  哥谭镇上有一臭名昭著的恶霸,人称小丑Joker,他作恶多端,欺行霸市。但哥谭镇的警察都收受了他的贿赂,所以他得以逍遥法外,为害苍生。

  小丑猖狂无边,觉得身边的人都太无聊:小混混为非作歹都没有创意,警察又太软弱。这个世界上只有一个人能够挑起他的好奇——蝙蝠侠。于是小丑不断挑衅蝙蝠侠的底线,带头作乱3年后,等着蝙蝠侠上门这个事件的发生。

  蝙蝠侠深知小丑狡诈多变,虽对小丑极度憎恶,但老管家一直劝他 “Son, you have to be patient.”,于是潜心修炼。终于在5年后,蝙蝠侠复出下山,身形矫健,身手了得,发出事件 “I'm coming for you!”。

  蝙蝠侠与小丑大战哥谭之巅,历时三年,双方战得难解难分,眼见小丑即将落败之际,使出阴险之计,诱骗蝙蝠侠保护平民,自己趁机遁逃。

  蝙蝠侠回身再战,小丑早已不见踪影,留下余音笼罩在哥谭镇的上空:“Sorry, you got missed.” 蝙蝠侠环顾四周道 “Your day will come, since I am back!”。

  欲知后事如何,且听下回分解。

Python——eventlet.event的更多相关文章

  1. Python——eventlet.hubs

    Hub构成了 Eventlet 的事件循环,它分发 I/O 事件.调度 greenthread.Hub的存在使得协程被提升为 greenthreads. Eventlet 有多种hub的实现,所以在使 ...

  2. Python——eventlet

    eventlet语境下的“绿色线程”普通线程之间的区别: 1. 绿色线程几乎没有开销,不用像保留普通线程一样保留“绿色线程”,每一个网络连接对应至少一个“绿色线程”: 2. 绿色线程需要人为的设置使其 ...

  3. Python——eventlet.backdoor

    eventlet.backdoor 是正在运行中的进程内的 Pyhon 交互解释器. 该模块便于检测一个长期运行进程的运行状态,提供了一种可以不阻塞应用正常操作的 Pyhon 交互解释器,从而极大地方 ...

  4. Python——eventlet.wsgi

    eventlet 的 wsgi 模块提供了一种启动事件驱动的WSGI服务器的简洁手段,可以将其作为某个应用的嵌入web服务器,或作为成熟的web服务器,一个这样的web服务器的例子就是 Spawnin ...

  5. Python线程event

    python线程的事件用于主线程控制其他线程的执行,事件主要提供了三个方法wait.clear.set 事件处理的机制:全局定义了一个“Flag”,如果“Flag”值为 False,那么当程序执行 e ...

  6. python 线程 event

    全局定义了一个“Flag”,如果“Flag”值为 False,那么当程序执行 event.wait 方法时就会阻塞,如果“Flag”值为True,那么执行event.wait 方法时便不再阻塞. cl ...

  7. Python多线程-Event(事件对象)

    Event 事件对象管理一个内部标志,通过set()方法将其设置为True,并使用clear()方法将其设置为False.wait()方法阻塞,直到标志为True.该标志初始为False. 方法: i ...

  8. python 多进程 Event的使用

    Event事件  多进程的使用 通俗点儿讲  就是 1.  Event().wait()    插入在进程中插入一个标记(flag)  默认为 false  然后flag为false时  程序会停止运 ...

  9. Python——eventlet.websocket

    使用该模块可以方便地创建 websocket 服务器,要创建一个websocket服务器,只需要将一个句柄函数用装饰器 WebSocketWSGI 装饰即可,然后这个函数就可以当做一个WSGI应用: ...

随机推荐

  1. Android 编程下 Eclipse 恢复被删除的文件

    开发过程中文件误删除,又没有 Git,SVN 等版本控制软件的备份,怎么办? Eclipse 自带了恢复历史文件的功能:在项目上点击右键,选择 Restore from Local History,在 ...

  2. (转)Linux下的输入/输出重定向

    Linux环境中支持输入输出重定向,用符号<和>来表示.0.1和2分别表示标准输入.标准输出和标准错误信息输出,可以用来指定需要重定向的标准输入或输出,比如 2>lee.dat 表示 ...

  3. 玩转Bootstrap(JS插件篇)-第1章 模态弹出框 :1-3 模态弹出框

    模态弹出框(Modals) 这一小节我们先来讲解一个“模态弹出框”,插件的源文件:modal.js. 右侧代码编辑器(30行)就是单独引入 bootstrap 中发布出的“modal.js”文件. 样 ...

  4. 开发openfire 消息拦截器插件PacketInterceptor

    开发消息拦截器的步骤跟开发简单插件步骤一样,要开发消息拦截器插件,首先继承PacketInterceptor包拦截类,然后在initializelPlugin()方法中注册拦截器,就可以实现inter ...

  5. 什么是内存溢出以及java中内存泄漏5种情况的总结

    内存泄漏定义(memory leak):一个不再被程序使用的对象或变量还在内存中占有存储空间. 一次内存泄漏似乎不会有大的影响,但内存泄漏堆积后的后果就是内存溢出.内存溢出 out of memory ...

  6. js实现冒泡事件,点击ul给子标签添加相同事件和阻止冒泡事件

    $('#LocalLife_PopUp_layer').find('.SelectCity_Cont ul').click(function(e){            var e=e||windo ...

  7. Django 批量保存图片文件 自定义上传方法

    1.前端通过formData的方式批量增加图片或文件 for (var i = 0; i < form_img_list.length; i++) { formData.append('imag ...

  8. 在pycharm中启动Django服务器

    1.要是直接运行manage.py程序的话 会提示一大堆东西,那无非是提示没有传入参数.先打开mange.py,然后再运行,会提示一堆东西,表示没有配置参数.在pycharm右上角点击edit con ...

  9. 【Bootstrap Method】Evaluating The Accuracy of a Classifier

    自助法介绍: 非参数统计中一种重要的估计统计量方差进而进行区间估计的统计方法,也称为自助法.其核心思想和基本步骤如下:(1)采用重抽样技术从原始样本中抽取一定数量(自己给定)的样本,此过程允许重复抽样 ...

  10. iOS友盟社会化分享U-Share分享面板不显示的问题(基本配置没有错误)

    //要先是window可视化 [self.window makeKeyAndVisible]; //添加友盟分享[[UMSocialManager defaultManager] openLog:YE ...