这两天用到 gevent 写个服务器,对于 join 的印象还是停留在比较模糊的阶段,好像就这么用着用着也没事 贴一下 greenlet 中 join 的相关源码,感觉 gevent 中比较绕的就是这个 switch ,所有类的方法都叫一个 switch 这里是讲当前 greenlet 的回调用 rawlink 注册到一个双端链表,然后再切换到 hub ,我看说 join 是当所有 greenlet 都运行完毕之后再依次回调,这个回调具体是咋操作的,又是怎么回到 main 的呢 还请好心朋友赐教一下,一言千金
def join(self, timeout=None):
"""Wait until the greenlet finishes or *timeout* expires.
Return ``None`` regardless.
"""
if self.ready():
return
switch = getcurrent().switch
self.rawlink(switch)
try:
t = Timeout._start_new_or_dummy(timeout)
try:
result = self.parent.switch()
if result is not self:
raise InvalidSwitchError('Invalid switch into Greenlet.join(): %r' % (result, ))
finally:
t.cancel()
except Timeout as ex:
self.unlink(switch)
if ex is not t:
raise
except:
self.unlink(switch)
raise
1
xueqt OP 来个人 O(∩_∩)O~
|
2
xueqt OP 不完全整明白吃不下饭啊,快来人帮个忙
|
3
zenliver 2016-08-11 11:54:35 +08:00
通过 greenlet 切换的
|
4
SlipStupig 2016-08-11 12:04:25 +08:00
@xueqt 说的很清楚了啊,直到任务完成或超时, grenlet 全部注册在 gevent Hub 里面,然后根据 greenlet 的定时去就主动切换,如果超时了就退出,剩下就是等任务完成了,然后从 Hub 取消注册,有点像回调注册!
|
5
xueqt OP @SlipStupig 是从 hub 取消注册后再回调 notify_link 吗
|
6
xueqt OP 明白了,虽然 join 没有向 hub 注册回调,但是当 Greenlet 结束最后会调用_report_result 方法,这时候_report_result 把将_notify_links 注册到 loop 的回调中,最后由_notify_links 回调之前注册在自己回调链上的 switch
|