源代码
loop = asyncio.get_event_loop()
task = asyncio.ensure_future(do_work(checker)) loop.run_until_complete(asyncio.wait([task])) st = task.result()
原因
在多线程运行中,loop变量调用被多次重复使用导致
解决方法
new_loop
=
asyncio.new_event_loop()
asyncio.set_event_loop(new_loop)
完成代码
new_loop
=
asyncio.new_event_loop()
asyncio.set_event_loop(new_loop)
loop
=
asyncio.get_event_loop()
task
=
asyncio.ensure_future(do_work(checker))
loop.run_until_complete(asyncio.wait([task]))
st
=
task.result()
根本原因在源码中:
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)):
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
在主线程中,调用get_event_loop总能返回属于主线程的event loop对象,如果是处于非主线程中,还需要调用set_event_loop方法指定一个event loop对象,这样get_event_loop才会获取到被标记的event loop对象:
def set_event_loog(self, loop):
"""Set the event loop."""
self._local._set_called = True
assert loop is None or isinstance(loop, AbstractEventLoop)
self._local._loop = loop
官方文档:Event Loop — Python 3.11.1 documentation
我只截取上述用到的部分具体详情请前往官方Event Loop — Python 3.11.1 documentation
事件循环
源代码: Lib / asyncio / events.py, Lib / asyncio / base_events.py
前言
事件循环是每个异步应用程序的核心。事件循环运行异步任务和回调,执行网络IO操作并运行子流程。
应用程序开发人员通常应使用高级异步函数(例如)asyncio.run(),并且几乎不需要引用循环对象或调用其方法。本部分主要面向需要更好地控制事件循环行为的较低级代码,库和框架的作者。
获取事件循环
以下低级函数可用于获取,设置或创建事件循环:
asyncio.
get_running_loop
()
返回当前OS线程中的运行事件循环。
如果没有正在运行的事件循环,RuntimeError则会引发一个。只能从协程或回调中调用此函数。
3.7版中的新功能
asyncio.
get_event_loop
()
获取当前事件循环。如果当前OS线程set_event_loop()中没有设置当前事件循环并且尚未调用,那么asyncio将创建一个新的事件循环并将其设置为当前事件循环。
因为此函数具有相当复杂的行为(尤其是在使用自定义事件循环策略时),所以 在协程和回调中get_running_loop()首选使用此 函数get_event_loop()。
还可以考虑使用该asyncio.run()函数,而不要使用较低级别的函数来手动创建和关闭事件循环。
asyncio.
set_event_loop
(循环)
将loop设置为当前OS线程的当前事件循环。
asyncio.
new_event_loop
()
创建一个新的事件循环对象。
需要注意的是行为get_event_loop(),set_event_loop()和new_event_loop()功能都可以通过改变 设置自定义事件循环政策。