Python asyncio 等待任务

手套

需要:Python 3.7 或更高版本。

两个函数main1main2定义如下。一个创建任务,然后在最后等待所有任务;另一个每次创建并等待。

虽然main1需要 2 秒,main2需要 30 秒。为什么?

import asyncio

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

async def main1():
    tasks = []
    for _ in range(10):
        task1 = asyncio.create_task(say_after(1, 'hello'))
        task2 = asyncio.create_task(say_after(2, 'world'))
        tasks.append(task1)
        tasks.append(task2)
    for x in tasks:
        await x

async def main2():
    for _ in range(10):
        await asyncio.create_task(say_after(1, 'hello'))
        await asyncio.create_task(say_after(2, 'world'))

asyncio.run(main2())

编辑 1:

这是一个main3版本,需要 20 秒。我会说整件事只是出于直觉:(

async def main3():
    for _ in range(10):
        task1 = asyncio.create_task(say_after(1, 'hello'))
        task2 = asyncio.create_task(say_after(2, 'world'))
        await task1
        await task2

编辑2:

(下面增加了一些示例代码)我读过从@freakish详细解答,我仍然停留在一个点上:因此,只有不断await的意志corporately并行(main4)的工作?

由于create_task()不花时间(是吗?),为什么不能同时2awaitmain5在后台运行,这样main5会花(TASK1,TASK2)的最大时间?

这种await机制是设计使然,还是只是一种asyncio限制(在设计或实施中)?

以及await官方 Python 文档中定义的任何详细行为?

# took 2 seconds
async def main4():
    task1 = asyncio.create_task(say_after(1, 'hello'))
    task2 = asyncio.create_task(say_after(2, 'world'))
    await task1
    await task2

# took 3 seconds
async def main5():
    task1 = asyncio.create_task(say_after(1, 'hello'))
    await task1
    task2 = asyncio.create_task(say_after(2, 'world'))
    await task2
怪异的

因为main1创建所有在同一时间的任务,然后等待所有这些都是建立在他们。一切都是并行发生的。所以总时间是所有时间中的最大值,即 2 秒。

main2只有在前一个任务完成才会创建一个新任务一切都按顺序发生。所以总时间是所有时间的总和(从代码来看)应该是 30 秒。

编辑:假设您有 3 个任务:task1, task2, task3. 如果你这样做

  1. 创建任务 1
  2. 等待任务1
  3. 创建任务 2
  4. 等待任务2
  5. 创建任务 3
  6. 等待任务3

那么总执行时间显然是task1.time + task2.time + task3.time因为没有后台处理。流程是连续的。现在让我们说你做

  1. 创建任务 1
  2. 创建任务 2
  3. 创建任务 3
  4. 等待任务1
  5. 等待任务2
  6. 等待任务3

现在task1, task2, task3 在后台运行所以需要T1 = task1.time处理 4。但是在 pt 5 需要T2 = max(task2.time - T1, 0)处理它,因为它已经在后台工作了T1一段时间。在 pt 6 需要T3 = max(task3.time - T2 - T1, 0)处理它,因为它已经在后台工作了T1+T2一段时间。现在需要一些数学来计算T1+T2+T3=max(task1.time, task2.time, task3.time).

但直觉是这样的:如果taskX是最长的并且它完成了,那么由于并行处理,其他一切都完成了。因此await立即返回使总处理时间成为所有时间中的最大值。

旁注:有细微差别:这仅在您实际执行可并行化的东西时才有效,例如asyncio.sleep(). 如果这些任务是同步的(比如一些 cpu 计算),那么两种情况都会给出 30 秒。

Edit2:所以你的main3流程有点不同。它允许两个任务并行运行。但没有更多:

  1. 创建任务 1
  2. 创建任务 2
  3. 等待任务1
  4. 等待任务2
  5. 创建任务 3
  6. 创建任务 4
  7. 等待任务3
  8. 等待任务4

所以这一次task1task2并行发生。但只过了,他们都做了,task3并且task4可以运行。在平行下。因此,对于每个组,总时间是最长的,但您必须将不同的组相加。即总执行时间max(task1.time, task2.time)+max(task3.time, task4.time)在您的情况下是

max(1,2) + ... + max(1,2) [10 times] = 20

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

asyncio等待多个任务超时和取消

来自分类Dev

Asyncio:发生异常时等待完成的任务

来自分类Dev

Python asyncio取消未等待的协程

来自分类Dev

等待在Python中使用asyncio下载

来自分类Dev

Python asyncio取消未等待的协程

来自分类Dev

python3 asyncio 等待回调

来自分类Dev

Python asyncio任务产生不良结果

来自分类Dev

asyncio-等待动态列表中的每个任务完成或被取消

来自分类Dev

Python Asyncio-等待条件满足的Pythonic方法

来自分类Dev

Python-asyncio-等待回调中的将来

来自分类Dev

Python3 Asyncio在并发任务之间共享资源

来自分类Dev

处理永不终止于python3 asyncio的任务

来自分类Dev

Python中带有asyncio的并行Web任务

来自分类Dev

在Python中的asyncio任务上拦截对__await__的调用

来自分类Dev

在Python asyncio任务中处理未处理的异常后整理

来自分类Dev

Python-asyncio-从未检索到任务异常

来自分类Dev

Python中带有asyncio的并行Web任务

来自分类Dev

python杀死等待排队的任务的线程

来自分类Dev

Python线程池-创建子任务并等待它们的任务

来自分类Dev

如何在 Python 3 asyncio 中实现同步等待回调?

来自分类Dev

没有 asyncio 的 Python 3.6 异步等待:如何编写自己最简单的事件循环?

来自分类Dev

Python 3 asyncio-vs asyncio的收益

来自分类Dev

为什么我在Python asyncio中收到“任务已销毁但正在挂起”错误?

来自分类Dev

Python asyncio-任务退出的循环退出已被破坏,但仍处于待处理状态

来自分类Dev

python asyncio,如何从另一个线程创建和取消任务

来自分类Dev

Python3 asyncio“任务已销毁,但正在挂起”,具有某些特定条件

来自分类Dev

如何正确处理Python的`asyncio.gather`中已取消的任务

来自分类Dev

python asyncio中的异常。直到主任务完成后才引发Task

来自分类Dev

Python asyncio简单示例

Related 相关文章

  1. 1

    asyncio等待多个任务超时和取消

  2. 2

    Asyncio:发生异常时等待完成的任务

  3. 3

    Python asyncio取消未等待的协程

  4. 4

    等待在Python中使用asyncio下载

  5. 5

    Python asyncio取消未等待的协程

  6. 6

    python3 asyncio 等待回调

  7. 7

    Python asyncio任务产生不良结果

  8. 8

    asyncio-等待动态列表中的每个任务完成或被取消

  9. 9

    Python Asyncio-等待条件满足的Pythonic方法

  10. 10

    Python-asyncio-等待回调中的将来

  11. 11

    Python3 Asyncio在并发任务之间共享资源

  12. 12

    处理永不终止于python3 asyncio的任务

  13. 13

    Python中带有asyncio的并行Web任务

  14. 14

    在Python中的asyncio任务上拦截对__await__的调用

  15. 15

    在Python asyncio任务中处理未处理的异常后整理

  16. 16

    Python-asyncio-从未检索到任务异常

  17. 17

    Python中带有asyncio的并行Web任务

  18. 18

    python杀死等待排队的任务的线程

  19. 19

    Python线程池-创建子任务并等待它们的任务

  20. 20

    如何在 Python 3 asyncio 中实现同步等待回调?

  21. 21

    没有 asyncio 的 Python 3.6 异步等待:如何编写自己最简单的事件循环?

  22. 22

    Python 3 asyncio-vs asyncio的收益

  23. 23

    为什么我在Python asyncio中收到“任务已销毁但正在挂起”错误?

  24. 24

    Python asyncio-任务退出的循环退出已被破坏,但仍处于待处理状态

  25. 25

    python asyncio,如何从另一个线程创建和取消任务

  26. 26

    Python3 asyncio“任务已销毁,但正在挂起”,具有某些特定条件

  27. 27

    如何正确处理Python的`asyncio.gather`中已取消的任务

  28. 28

    python asyncio中的异常。直到主任务完成后才引发Task

  29. 29

    Python asyncio简单示例

热门标签

归档