Python 异步 : event loop does not seem to stop when stop method is called

标签 python multithreading 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 而事件循环没有更多的工作要做,但这似乎是一个很有问题的限制。

或者我可能误解了它应该如何工作?

最佳答案

文档 says关于事件循环类:

This class is not thread safe.

further :

An event loop runs in a thread and executes all callbacks and tasks in the same thread. [...] To schedule a callback from a different thread, the AbstractEventLoop.call_soon_threadsafe() method should be used. Example:

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 异步 : event loop does not seem to stop when stop method is called,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46093238/

相关文章:

python - 这个多线程函数是异步的吗

java - 如何从 JUnit 线程中断信号量?

Python 2.6 使用系统编码在 C-API 中写入字符串

python - 将列表中的项目映射到列表列表

python - Mongodb pymongo.errors.ServerSelectionTimeoutError : localhost:27017: [Errno 111] Connection refused, 超时: 30s,

java - Java有可索引的多队列线程池吗?

c# - 为什么在finally block 中休眠时线程不被中断

python - 如何检查函数是否阻塞?

Python - 将数据从文件流式传输到启用异步的 Kinesis Producer

python - azure 函数绑定(bind)日期时间昨天