在看 nameko 的源码的时候,常常看到 gt.link(self._handle_thread_exited) 的用法

def spawn_managed_thread(self, run_method):    """ Spawn a lifecycle-managed thread, which calls the ``run_method``    once it has been started.    Any errors raised inside the ``run_method`` cause the container to be    killed.    It is the entrypoint provider's responsibility to react to ``stop()``    calls and terminate it's spawned threads.    Threads are killed automatically by the container if they are    still running after all their providers have been stopped.    Entrypoints may only create separate threads using this method,    to ensure they are life-cycle managed.    """    gt = eventlet.spawn(run_method)    self._active_threads.add(gt)    gt.link(self._handle_thread_exited)    return gt

eventlet 的文档中,并没有形容这个 api 是干嘛的,所以我看了一下 eventlet 源码,其中有对于他的正文:

def link(self, func, *curried_args, **curried_kwargs):    """ Set up a function to be called with the results of the GreenThread.    The function must have the following signature::        def func(gt, [curried args/kwargs]):    When the GreenThread finishes its run, it calls *func* with itself    and with the `curried arguments <http://en.wikipedia.org/wiki/Currying>`_ supplied    at link-time.  If the function wants to retrieve the result of the GreenThread,    it should call wait() on its first argument.    Note that *func* is called within execution context of    the GreenThread, so it is possible to interfere with other linked    functions by doing things like switching explicitly to another    greenthread.    """    if self._exit_funcs is None:        self._exit_funcs = deque()    self._exit_funcs.append((func, curried_args, curried_kwargs))    if self._exit_event.ready():        self._resolve_links()

英文是看不懂的,就用翻译软件翻译一下吧:

原文:

Set up a function to be called with the results of the GreenThread.        The function must have the following signature::            def func(gt, [curried args/kwargs]):        When the GreenThread finishes its run, it calls *func* with itself and with the `curried arguments <http://en.wikipedia.org/wiki/Currying>`_ supplied at link-time.  If the function wants to retrieve the result of the GreenThread,it should call wait() on its first argument.        Note that *func* is called within execution context of the GreenThread, so it is possible to interfere with other linked functions by doing things like switching explicitly to another greenthread.

译文:

设置一个函数,用GreenThread的后果来调用。        该函数必须有以下签名:。            def func(gt, [curried args/kwargs])。        当GreenThread实现其运行时,它用本人和在链接时提供的`curried arguments <http://en.wikipedia.org/wiki/Currying>`_调用*func*。 如果该函数想获取GreenThread的后果,它应该在其第一个参数上调用wait()。        请留神,*func*是在GreenThread的执行上下文中调用的,所以有可能会烦扰到其余链接的函数,比方明确地切换到另一个Greenthread。

所以,这 link 是干啥的?其实就是一个回调函数注册器

import eventletfrom loguru import loggerdef func():    logger.debug('执行 func')def call_back_func(gt):    logger.debug('执行 回调函数')t1 = eventlet.spawn(func)t2 = eventlet.spawn(func)t3 = eventlet.spawn(func)t1.link(call_back_func)t2.link(call_back_func)t3.link(call_back_func)t1.wait()t2.wait()t3.wait()

执行后果

2022-09-04 12:58:46.889 | DEBUG    | __main__:func:6 - 执行 func2022-09-04 12:58:46.889 | DEBUG    | __main__:call_back_func:10 - 执行 回调函数2022-09-04 12:58:46.889 | DEBUG    | __main__:func:6 - 执行 func2022-09-04 12:58:46.889 | DEBUG    | __main__:call_back_func:10 - 执行 回调函数2022-09-04 12:58:46.889 | DEBUG    | __main__:func:6 - 执行 func2022-09-04 12:58:46.889 | DEBUG    | __main__:call_back_func:10 - 执行 回调函数