【问题标题】:Asyncio example in PythonPython 中的异步示例
【发布时间】:2021-04-07 07:58:30
【问题描述】:

我正在尝试学习原生协程。 上面的例子我跑了,没看懂。

这是一个例子。

import asyncio

async def say_after(delay, what):
    await asyncio.sleep(delay)
    print(what)

async def main():
    task1 = asyncio.create_task(
        say_after(3, "A")
    )
    
    task2 = asyncio.create_task(
        say_after(2, "B")
    )

    print("----0")
    await task1
    print("----1")
    await task2

asyncio.run(main())

听说await 等待任务完成。 我希望按顺序打印

A
B
----1

但是,在上面的示例中,----1BA 都被打印之后输出。

以下是打印的输出。

----0
B
A
----1

为什么要创建这个输出?

你知道有一个网站收集了学习原生协程的有用示例吗?

【问题讨论】:

    标签: python async-await python-asyncio


    【解决方案1】:

    这是时间轴上发生的事情:

    0秒后:

    • task1 开始
    • task2 开始
    • 输出---0
    • await task1

    2 秒后:

    • task2 打印 B 并完成

    3 秒后:

    • task1 打印 A 并完成
    • await task1返回
    • 输出---1
    • await task2 返回(任务已在 1 秒前完成)

    【讨论】:

    • 为什么 ------1 出现在最后?我认为输出应该是 ----0 ------1 B A. 我在这里缺少什么部分?
    【解决方案2】:

    无法保证异步任务的运行顺序。您唯一的保证是当您await 时,main 中的任务执行将停止,直到该任务完成。以下是你的程序的所有有效输出,你不能假设你会得到任何一个特别的输出:

    A
    B
    ----0
    ----1
    
    B
    A
    ----0
    ----1
    
    ----0
    A
    B
    ----1
    
    ----0
    B
    A
    ----1
    
    A
    ----0
    B
    ----1
    
    B
    ----0
    A
    ----1
    
    A
    ----0
    ----1
    B
    
    ----0
    A
    ----1
    B
    

    【讨论】:

    • ---0 总是在 AB 之前,因为这两个任务分别休眠 2 或 3 秒,而 main 函数运行。 A 总是在 B 之后,因为 task2 比 task1 早 1 秒唤醒。
    • tbh 我不知道是否保证sleep(2)sleep(3) 更早醒来,但我认为如果不这样做会出现严重错误。
    • @mkrieger1 在实践中,几乎可以肯定。但不能保证。 print 在内部实现为异步并且可能需要最多 4 秒才能完成的系统可能会产生这些结果(愚蠢的例子)。
    • 这是一个令人信服的论点。
    • 为什么 ------1 出现在最后?我认为输出应该是 ----0 ------1 B A. 我在这里缺少什么部分?
    猜你喜欢
    • 2018-01-29
    • 2019-09-25
    • 1970-01-01
    • 2021-09-13
    • 2020-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多