3

为什么get_event_loopasyncio (source)中的方法正在检查当前线程是否是主线程(请参阅下面片段中的评论)?

def get_event_loop(self):
    """Get the event loop.

    This may be None or an instance of EventLoop.
    """
    if (self._local._loop is None and
        not self._local._set_called and
        isinstance(threading.current_thread(), threading._MainThread)):  # <- I mean this thing here
        self.set_event_loop(self.new_event_loop())
    if self._local._loop is None:
        raise RuntimeError('There is no current event loop in thread %r.'
                           % threading.current_thread().name)
    return self._local._loop 
4

1 回答 1

4

为方便起见,asyncio 支持自动创建事件循环,而无需调用new_event_loop()set_event_loop()。由于事件循环的创建成本适中,并且会消耗一些操作系统资源,因此它不是在导入时自动创建,而是按需创建,特别是在第一次调用get_event_loop(). (这个特性大部分已经过时了,asyncio.run它总是创建一个新的事件循环,然后自动创建的会导致问题。)

然而,这种便利是为主线程保留的——任何其他线程都必须显式设置事件循环。这有几个可能的原因:

  • 防止混淆 - 您不希望get_event_loop()从任意线程意外调用以占用该线程的“主”(自动创建)事件循环;
  • 当或要求事件循环在主线程中运行时,某些 asyncio 功能效果最佳 - 例如,进程和信号处理

这些问题也可以通过在每个调用的线程中自动创建一个新的事件循环来避免get_event_loop(),但这很容易意外创建多个事件循环,其协程将无法相互通信,这将违背 asyncio 的设计. 所以剩下的选择是让代码对主线程进行特殊处理,鼓励开发人员使用该线程来执行异步代码。

于 2019-04-12T21:27:30.777 回答