为什么我不能在一个已经通过run_forever启动的事件循环上继续提交任务?

编程语言 2026-07-09

我正在尝试建模一个使用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导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章