You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何协程'hello_world'无法正确执行await操作?

问题原因与解决方案

为什么程序会提前终止?

核心问题出在asyncio.run()的工作机制上:它会运行你传入的主协程,直到该协程完全执行完毕,随后立刻关闭事件循环。你的代码流程里,func_runner这个主协程在调用完not_a_coroutine()之后就没有后续逻辑了,会快速执行完毕,导致asyncio.run()直接关闭事件循环——这时候你通过loop.create_task()创建的hello_world任务甚至还没来得及真正进入休眠阶段(刚打印完"Hello"就被强制取消),自然不会等到一年的休眠结束。

具体拆解你的代码执行顺序:

  1. asyncio.run(func_runner(not_a_coroutine))启动事件循环,开始运行func_runner协程
  2. func_runner执行await asyncio.sleep(0),只是短暂让出控制权,很快回到协程继续执行
  3. 调用普通函数not_a_coroutine(),它获取当前运行的事件循环,创建coro_runner(hello_world)的任务并加入循环
  4. not_a_coroutine()执行完毕,回到func_runner,此时func_runner没有更多代码,协程执行完成
  5. asyncio.run()检测到主协程结束,立刻关闭事件循环,所有未完成的任务(包括hello_world)被强制取消,程序直接退出

你看到只打印了"Hello",是因为hello_world刚执行到打印语句,还没进入await asyncio.sleep(...)的休眠,事件循环就被关闭了。


如何修复这个问题?

要解决问题,核心是让asyncio.run()运行的主协程(也就是func_runner)等待你在普通函数里创建的hello_world任务完成。这里提供一种直观的修改方案:

import asyncio
from typing import Callable

async def hello_world():
    print('Hello', end=' ')
    await asyncio.sleep(31_536_000) # 1 Year
    print('world.')

async def func_runner(func: Callable):
    await asyncio.sleep(0)
    # 获取普通函数创建的任务,并等待它完成
    task = func()
    await task

async def coro_runner(func: Callable):
    await func() # 调用hello_world

def not_a_coroutine():
    loop = asyncio.get_running_loop()
    task = loop.create_task(coro_runner(hello_world))
    # 返回创建的任务,让主协程可以等待它
    return task

asyncio.run(func_runner(not_a_coroutine))

修改点说明:

  • 让not_a_coroutine()返回创建的任务对象
  • 在func_runner中接收这个任务对象,并通过await task等待它完成
  • 这样func_runner会一直等待hello_world任务执行完毕,asyncio.run()才会关闭事件循环,你的休眠逻辑就能正常工作了

内容的提问来源于stack exchange,提问作者lemi57ssss

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 14:12:52