【问题标题】:Calling asyncio task调用异步任务
【发布时间】:2021-04-03 22:37:49
【问题描述】:

我有密码。为什么退出 asyncio main 时没有调用任务?调用任务的逻辑是什么?

async def func1():
    print('func1')
    ### task2 = asyncio.create_task(func2())
    return 'func1-result'

async def func2():
    print('func2')
    return 'func2-result'

async def main():
    print('main')
    task1 = asyncio.create_task(func1())
    task2 = asyncio.create_task(func2())
    return 'main-result'

res = asyncio.run(main())

我进入标准输出:

main
func1
func2

但如果我这样做:

import asyncio

async def func1():
    print('func1')
    task2 = asyncio.create_task(func2())
    return 'func1-result'

async def func2():
    print('func2')
    return 'func2-result'

async def main():
    print('main')
    task1 = asyncio.create_task(func1())
    ### task2 = asyncio.create_task(func2())
    return 'main-result'

res = asyncio.run(main())
main
func1

为什么第一种情况task2进入事件循环并执行,而第二种情况却没有?

【问题讨论】:

  • 你的程序在 task2 运行前退出
  • 第一种情况下task1运行前退出
  • 退出有一些开销,显然调度task1就足够了。

标签: python python-3.x python-asyncio


【解决方案1】:
import asyncio

async def func1():
    print('func1')
    task2 = asyncio.create_task(func2())
    return 'func1-result'

async def func2():
    print('func2')
    return 'func2-result'

async def main():
    print('main')
    task1 = await asyncio.create_task(func1())
    ### task2 = asyncio.create_task(func2())
    return 'main-result'

res = asyncio.run(main())

确实有效,你应该等待函数的结果,因为你没有在函数关闭后传递结果。并且等待是必要的,因为在任务1关闭之前函数2的结果还没有准备好,等待是让 func2 在关闭 func1 之前完成。

【讨论】:

  • 用 await 很清楚。但是我的两个案例有什么区别
【解决方案2】:

当您通过asyncio.runloop.run_until_complete 运行事件循环时,循环会为在协程完成之前安排的所有任务提供最后一次运行机会(这实际上是一种停止循环的行为)。在您的第一个示例中,在main 完成之前为func1func2 中的每一个安排一个任务。在您的第二个示例中,在main 完成之前为func1 安排了一个任务。但由于func1 直到main 完成后才能运行,所以func2 的任务被安排得太晚并且永远不会运行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-16
    • 2019-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多