ref=True/False 参数在 gevent sleep 中有什么作用?
What does ref=True/False parameter do in gevent sleep?
gevent.sleep()
函数的文档对其 ref=True/False
参数说明如下:
def sleep(seconds=0, ref=True):
"""
If *ref* is False, the greenlet running ``sleep()`` will not prevent :func:`gevent.wait`
from exiting.
"""
有人知道这是什么意思吗?我已经多次尝试 google 更详细地解释 ref
参数的作用,但奇怪的是,我在互联网上能找到的所有解释都是同一句话,没有更多细节。
在什么情况下传递 ref=False
是有意义的(正如您在函数定义中看到的那样,默认情况下它是 True
)?
它现在似乎没有做任何事情。这需要对代码进行大量挖掘,但基本上当您调用 sleep
函数时会发生以下事件链。
sleep
是从 gevent.hub
导入的。
- 在
gevent.hub.sleep
的代码中我们看到 loop.timer(seconds, ref)
。
loop
来自hub.loop
,来自hub = _get_hub_noargs()
,_get_hub_noargs
来自gevent._hub_local
线索在这里变得有点冷淡,但通过搜索代码以查找对 ref
和 timer
的引用会发现一些有趣的 classes。
gevent.libev.timer
是上面loop.timer
中调用的class。它是 gevent.libev.watcher
的子 class。
gevent.libev.watcher
是我们最终看到对 ref
. 发生的事情的引用
gevent.libev.timer
还引用了一个 loop
对象(稍后会详细介绍)。
根据 ref
的设置方式,某些操作在继承自 watcher
的 class 上会发生或不会发生。特别是,它会调用 self.loop.ref()
或 self.loop.unref()
。如此处所示:
class watcher(_base.watcher):
...
def _watcher_ffi_ref(self):
if self._flags & 2: # we've told libev we're not referenced
self.loop.ref()
self._flags &= ~2
def _watcher_ffi_unref(self):
if self._flags & 6 == 4:
# We're not referenced, but we haven't told libev that
self.loop.unref()
self._flags |= 2 # now we've told libev
...
查看 gevent.libuv.loop
的代码,我们发现 loop
class。但是,当您查看 ref
和 unref
方法时,它们什么都不做。
@implementer(ILoop)
class loop(AbstractLoop):
...
def ref(self):
pass
def unref(self):
# XXX: Called by _run_callbacks.
pass
...
我可能完全遗漏了一些东西,但据我所知,这些是将来会实现的方法。
gevent.sleep()
函数的文档对其 ref=True/False
参数说明如下:
def sleep(seconds=0, ref=True):
"""
If *ref* is False, the greenlet running ``sleep()`` will not prevent :func:`gevent.wait`
from exiting.
"""
有人知道这是什么意思吗?我已经多次尝试 google 更详细地解释 ref
参数的作用,但奇怪的是,我在互联网上能找到的所有解释都是同一句话,没有更多细节。
在什么情况下传递 ref=False
是有意义的(正如您在函数定义中看到的那样,默认情况下它是 True
)?
它现在似乎没有做任何事情。这需要对代码进行大量挖掘,但基本上当您调用 sleep
函数时会发生以下事件链。
sleep
是从gevent.hub
导入的。- 在
gevent.hub.sleep
的代码中我们看到loop.timer(seconds, ref)
。 loop
来自hub.loop
,来自hub = _get_hub_noargs()
,_get_hub_noargs
来自gevent._hub_local
线索在这里变得有点冷淡,但通过搜索代码以查找对 ref
和 timer
的引用会发现一些有趣的 classes。
gevent.libev.timer
是上面loop.timer
中调用的class。它是gevent.libev.watcher
的子 class。gevent.libev.watcher
是我们最终看到对ref
. 发生的事情的引用
gevent.libev.timer
还引用了一个loop
对象(稍后会详细介绍)。
根据 ref
的设置方式,某些操作在继承自 watcher
的 class 上会发生或不会发生。特别是,它会调用 self.loop.ref()
或 self.loop.unref()
。如此处所示:
class watcher(_base.watcher):
...
def _watcher_ffi_ref(self):
if self._flags & 2: # we've told libev we're not referenced
self.loop.ref()
self._flags &= ~2
def _watcher_ffi_unref(self):
if self._flags & 6 == 4:
# We're not referenced, but we haven't told libev that
self.loop.unref()
self._flags |= 2 # now we've told libev
...
查看 gevent.libuv.loop
的代码,我们发现 loop
class。但是,当您查看 ref
和 unref
方法时,它们什么都不做。
@implementer(ILoop)
class loop(AbstractLoop):
...
def ref(self):
pass
def unref(self):
# XXX: Called by _run_callbacks.
pass
...
我可能完全遗漏了一些东西,但据我所知,这些是将来会实现的方法。