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

线索在这里变得有点冷淡,但通过搜索代码以查找对 reftimer 的引用会发现一些有趣的 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。但是,当您查看 refunref 方法时,它们什么都不做。

@implementer(ILoop)
class loop(AbstractLoop):

    ...

    def ref(self):
        pass

    def unref(self):
        # XXX: Called by _run_callbacks.
        pass

    ...

我可能完全遗漏了一些东西,但据我所知,这些是将来会实现的方法。