调用stop方法时事件循环似乎没有停止

调用stop方法时事件循环似乎没有停止

本文介绍了Python asyncio:调用stop方法时事件循环似乎没有停止的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I've got a simple test where I run a Python asyncio event loop using the run_forever method, and then immediately stop it in another thread. However, the event loop does not seem to terminate. I have the following test case:

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() 上阻塞,等待事件循环终止.

So, the test seems to block on thread.join(), waiting for the event loop to terminate.

如果我转储我的线程,我会得到以下信息:

If I dump my threads I get the following:

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 而事件循环没有更多的工作,但这似乎是一个相当有问题的限制.

I haven't looked to deeply at the Python code, but selectors.py seems to be waiting for work. I guess it's possible that this problem is occurring because I've called stop while there is no more work for the event loop to so, but this seems like it could be quite a problematic limitation.

也许我误解了它应该如何工作?

Or maybe I've misunderstood something about how this should work?

推荐答案

文档 关于事件循环类:

Documentation says about event loop class:

这个类不是线程安全的.

以及进一步:

一个事件循环在一个线程中运行,并在同一个线程中执行所有回调和任务.[...]要从不同的线程安排回调,应该使用 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!

这篇关于Python asyncio:调用stop方法时事件循环似乎没有停止的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 10:06