Python Asyncio:当调用停止方法时,事件循环似乎并不停止



我有一个简单的测试,其中我使用run_forever方法运行Python asyncio事件循环,然后立即将其停在另一个线程中。但是,事件循环似乎并未终止。我有以下测试案例:

import asyncio
from threading import Thread
loop = asyncio.get_event_loop()
thread = Thread(target=loop.run_forever)
thread.start()
print('Started!')
loop.stop()
print('Requested stop!')
thread.join()
print('Finished!')

此测试案例打印:

Started!
Requested stop!

因此,测试似乎在thread.join()上阻塞,等待事件循环终止。

如果我倾倒了线程,则会得到以下内容:

Thread 0x00007000087ec000 (most recent call first):
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/selectors.py", line 577 in select
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/asyncio/base_events.py", line 1388 in _run_once
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/asyncio/base_events.py", line 421 in run_forever
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/threading.py", line 862 in run
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/threading.py", line 914 in _bootstrap_inner
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/threading.py", line 882 in _bootstrap
Current thread 0x00007fffc6b273c0 (most recent call first):
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/threading.py", line 1070 in _wait_for_tstate_lock
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/threading.py", line 1054 in join

我还没有深入研究Python代码,但是selectors.py似乎正在等待工作。我想这个问题可能发生了,因为我已经打电话给stop,而事件循环没有更多的工作,但这似乎是一个有问题的限制。

或也许我已经误解了如何工作的一些东西?

文档说明事件循环类:

此类不是线程安全。

和进一步:

事件循环在线程中运行,并在同一线程中执行所有回调和任务。[...] 为了安排来自其他线程的回调, 应使用AbstractEventloop.call_soon_threadsafe()方法。 示例:

loop.call_soon_threadsafe(callback, *args)

似乎是我们需要的:

import asyncio
from threading import Thread
loop = asyncio.get_event_loop()
thread = Thread(target=loop.run_forever)
thread.start()
print('Started!')
loop.call_soon_threadsafe(loop.stop)  # here
print('Requested stop!')
thread.join()
print('Finished!')

打印:

Started!
Requested stop!
Finished!

最新更新