需要:Python 3.7 或更高版本。
两个函数main1
,main2
定义如下。一个创建任务,然后在最后等待所有任务;另一个每次创建并等待。
虽然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()
不花时间(是吗?),为什么不能同时2await
中main5
在后台运行,这样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
. 如果你这样做
那么总执行时间显然是task1.time + task2.time + task3.time
因为没有后台处理。流程是连续的。现在让我们说你做
现在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
流程有点不同。它允许两个任务并行运行。但没有更多:
所以这一次task1
和task2
并行发生。但只过了,他们都做了,task3
并且task4
可以运行。在平行下。因此,对于每个组,总时间是最长的,但您必须将不同的组相加。即总执行时间max(task1.time, task2.time)+max(task3.time, task4.time)
在您的情况下是
max(1,2) + ... + max(1,2) [10 times] = 20
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句