我们来看event类, eventlet.event.Event
class NOT_USED:
def __repr__(self):
return 'NOT_USED'
# 这个单例子用来做is判断
# 比直接用字符串比较来的快
# 还能输出字符串
# 又学习到新方法
NOT_USED = NOT_USED()
class Event(object):
_result = None
_exc = None
def __init__(self):
# 一个列表用于存放正在等待的绿色线程
# 这里可以看出这个Event是可能被多个绿色线程调用
self._waiters = set()
# 初始化self._result、self._exc值
self.reset()
def wait(self):
# 每当绿色线程调用指定wait的时候,_waiters列表中就会添加当前绿色线程
# 表明这个绿色线程讲等待event被其他绿色线程调用send
# waiter是用于存放等待返回值的绿色线程合集
# 多个waiter的情况用于多个绿色线程等待一个返回值
# 需要自己编写相应代码
# 在GreenThread类中,每个GreenThread实例有自己的event
# 所以GreenThread中event
# 只是用来收发这个GreenThread实例中的function的返回值的
current = greenlet.getcurrent()
# _result还是默认标记,说明send还没有被调用过
# 把自己注册到等待返回值的列表中
# 也就是添加到self._waiters中
if self._result is NOT_USED:
# 把当前绿色线程放入_waiters这个list中
# 这里看出_waiters的作用了
# 多个绿色线程等待一个函数的返回值
self._waiters.add(current)
try:
# 先切换到main loop
# 切换回来的时候
# 获取到返回值,返回值是其他绿色线程调用switch的参数
# 所谓的其他绿色线程其实就是_do_send里
# 调用的waiter.switch(result)
return hubs.get_hub().switch()
finally:
# returen前把_waiters中的当前绿色线删除(discard方法不报错)
self._waiters.discard(current)
# 如果self._exc不为空通过绿色线程throw异常
if self._exc is not None:
current.throw(*self._exc)
# 走到这里说明已经有返回值了
# 也就是说有绿色线程注册到event表面要获取返回值
# 但是event已经被外部调用过send了
# 那么就直接返回返回值即可
# 也就不用注册到self._waiters列表里了
return self._result
def send_exception(self, *args):
# 发送一个exception
return self.send(None, args)
def send(self, result=None, exc=None):
# GreenThread被switch到
# GreenThread.main()中执行完外部function后
# 外部function的返回值会通过
# event.send来发送
# self._result还是默认标记才能send
assert self._result is NOT_USED, 'Trying to re-send() an already-triggered event.'
# 设置_result
self._result = result
if exc is not None and not isinstance(exc, tuple):
exc = (exc, )
self._exc = exc
hub = hubs.get_hub()
# 如果_waiters为空,那么说明
# 还没有有绿色线程注册到event里表示它要获取send的结果
# 否则,将_waiters中所有绿色线程作为参数
# 在Hub里创建多个定时器(最终main loop中调用)来swith到对应绿色线程
# 这里绕了一下没有直接调用waiter.switch
for waiter in self._waiters:
hub.schedule_call_global(
0, self._do_send, self._result, self._exc, waiter)
def _do_send(self, result, exc, waiter):
# 这里再次判断waiter是否还在_waiters中
# 因为可能会被其他绿色线程cancel掉
if waiter in self._waiters:
# 可以看出返回值是通过switch来发送的
if exc is None:
waiter.switch(result)
else:
waiter.throw(*exc)
event类大致看完其实我们还不知道如何使用,我们先回到eventlet使用,绿色线程工作原理中继续后面的部分
这样才能看懂event类具体的使用