ref = True / False参数在gevent睡眠中有什么作用?

时间:2019-12-18 12:10:17

标签: python gevent

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.
    """

有人知道这意味着什么吗?我已经尝试过多次搜索ref参数的作用的详细说明,但是,很奇怪的是,我在互联网上能找到的所有解释都是同一句话,没有更多细节。

通过ref=False(在函数定义中默认为True)有意义吗?

1 个答案:

答案 0 :(得分:0)

现在似乎什么也不做。这花了很多时间来研究代码,但是基本上,当您调用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的引用会发现一些有趣的类。

  • gevent.libev.timer是上面loop.timer中调用的类。它是gevent.libev.watcher的子类。
  • gevent.libev.watcher是我们最终看到ref所发生情况的参考。
  • gevent.libev.timer还引用了loop对象(稍后会对此进行更多介绍)。

取决于如何设置ref,某些操作在从watcher继承的类上是否发生。特别是,它将调用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类。但是,当您查看refunref方法时,它们什么也没做。

@implementer(ILoop)
class loop(AbstractLoop):

    ...

    def ref(self):
        pass

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

    ...

我可能会完全丢失一些东西,但是据我所知,这些方法将在将来实现。