Create_task()是做什么的?

asyncio.create_task()是做什么的?我看了那些文件,似乎看不懂。有一段代码让我很困惑:

import asyncio


async def counter_loop(x, n):
for i in range(1, n + 1):
print(f"Counter {x}: {i}")
await asyncio.sleep(0.5)
return f"Finished {x} in {n}"


async def main():
slow_task = asyncio.create_task(counter_loop("Slow", 4))
fast_coro = counter_loop("Fast", 2)


print("Awaiting Fast")
fast_val = await fast_coro
print("Finished Fast")


print("Awaiting Slow")
slow_val = await slow_task
print("Finished Slow")


print(f"{fast_val}, {slow_val}")


asyncio.run(main())

结果如下:

001 | Awaiting Fast
002 | Counter Fast: 1
003 | Counter Slow: 1
004 | Counter Fast: 2
005 | Counter Slow: 2
006 | Finished Fast
007 | Awaiting Slow
008 | Counter Slow: 3
009 | Counter Slow: 4
010 | Finished Slow
011 | Finished Fast in 2, Finished Slow in 4

我不太明白这是怎么回事。

  1. 难道 slow_task不能运行,直到完成 因为它从未在 asyncio.gather中使用过 方法?
  2. 为什么我们必须 await slow_task
  3. 为什么 Awaiting Slow打印后,协程似乎已经开始?
  4. 任务到底是什么? 我知道 gather正在做的是安排一个 据推测,create_task创建了一个任务。

如能给我一个深入的回答,我将不胜感激。谢谢!

也许值得一提的是,我对期货知之甚少。

46883 次浏览

asyncio.create_task()是做什么的?

它提交协程“在后台”运行,即与当前任务和所有其他任务同时运行,在 await点在它们之间切换。它返回一个称为“任务”的可等待句柄,您也可以使用该句柄取消协程的执行。

它是异步的核心原语之一,异步相当于启动一个线程。(同样地,用 await等待任务等同于加入一个线程。)

难道 slow_task不能运行,直到完成 fast_coro

不,因为你明确地使用 create_task在后台启动 slow_task。你有没有写过这样的东西:

    slow_coro = counter_loop("Slow", 4)
fast_coro = counter_loop("Fast", 2)
fast_val = await fast_coro

... 事实上 slow_coro不会运行,因为没有人会把它提交到事件循环。但是 create_task正是这样做的: 将它提交给事件循环以便与其他任务同时执行,切换的点是任何 await

因为它从未在 asyncio.gather方法中使用过?

asyncio.gather不是在异步中实现并发的唯一方法。它只是一个实用函数,使得等待许多协程完成并同时将它们提交给事件循环变得更加容易。create_task只是提交,它可能应该被称为 start_coroutine或类似的东西。

为什么我们要等待 slow_task

我们没有 ,它只是服务于等待两个协程完成干净。代码也可能等待 asyncio.sleep()或类似的东西。立即从 main()(和事件循环)返回一些仍然挂起的任务也可以工作,但是它会打印一个警告消息来指示可能的错误。在停止事件循环之前等待(或取消)任务更简单。

任务到底是什么?

它是一个异步构造,用于跟踪具体事件循环中协程的执行。当您调用 create_task时,您将提交一个执行的协程,并收到一个句柄。您可以在实际需要结果时等待这个句柄,或者如果您不关心结果,则永远不能等待它。这个句柄是 任务,它继承自 Future,这使得它可以等待,并提供基于回调的底层接口,比如 add_done_callback