为什么我不能在一个已经通过run_forever启动的事件循环上继续提交任务?
我正在尝试建模一个使用asyncio和事件循环的系统。我发现如果创建一个事件循环,并用run_forever启动,它在没有未完成任务时不会处理新任务。
import asyncio, threading, time
loop = asyncio.new_event_loop()
那是我的循环,则我启动它
thread = threading.Thread( target = loop.run_forever)
thread.start()
在我看来,这个循环应该有一个正在运行的事件循环,我可以向它提交新的任务。
async def dostuff( i ):
await asyncio.sleep(5)
print("doing something", i)
loop.create_task( dostuff(0) )
那将永远不会运行,除非循环中有未完成的任务。
async def main(self, ):
print("keep alive running")
while True:
await asyncio.sleep(0.1)
接着启动循环。
thread = threading.Thread( target = loop.run_forever)
loop.create_task( main() )
thread.start()
现在 loop.create_task 将创建并运行一个任务。为什么如果没有正在运行的任务,事件循环还会继续处理任务?
解决方案
当你在一个在不同线程中运行的循环中提交要执行的任务时,必须使用 run_coroutine_threadsafe。
这个调用会唤醒事件循环,这是解释你所经历现象的一个重要区别。当事件循环空闲时,它不会注意到回调队列中新项的加入。另一方面,如果它始终处于忙碌状态,它会在每次迭代时检查队列,并会注意到新的任务。
一般来说,当在一个不是从asyncio本身内部调用的函数中创建一个asyncio任务时,使用 ..._threadsafe 函数来唤醒循环。这也包括信号处理程序。
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。