Lor*_*zoC 7 python task coroutine python-3.x python-asyncio
我正在使用 Python 3.10,我对asyncio.create_task.
在下面的示例代码中,无论我是否使用asyncio.create_task. 似乎没有什么区别。
如何确定何时使用以及使用与不使用相比asyncio.create_task有何优势?asyncio.create_task
import asyncio
from asyncio import sleep
async def process(index: int):
    await sleep(1)
    print('ok:', index)
async def main1():
    tasks = []
    for item in range(10):
        tasks.append(asyncio.create_task(process(item)))
    await asyncio.gather(*tasks)
async def main2():
    tasks = []
    for item in range(10):
        tasks.append(process(item)) # Without asyncio.create_task
    await asyncio.gather(*tasks)
asyncio.run(main1())
asyncio.run(main2())
Dan*_*erg 10
如果您想立即create_task安排该协程的执行,但不一定要等待它完成,而是先继续执行其他操作,那么使用 是有意义的。
正如评论中已经指出的那样,asyncio.gather它本身将提供的可等待项包装在任务中,这就是为什么create_task在简单的示例中预先调用它们本质上是多余的。
来自gather文档:
如果任何可等待的 [...] 是协程,则会自动将其安排为任务。
话虽如此,您构建的两个示例并不等效!
当您调用 时create_task,任务会立即安排在偶循环上执行。这意味着,如果在调用所有协程之后发生上下文切换create_task(如第一个示例中所示),则任意数量的协程都可以立即开始执行,而无需显式执行await它们。
来自create_task文档:(我的重点)
将 [...] 协程包装到 a 中
Task并安排其执行。
相比之下,当您简单地创建协程(如第二个示例中所示)时,它们不会自行开始执行,除非您以某种方式安排它们的执行(例如,通过简单地await执行它们)。
如果您在创建和调用之间添加任何await(例如)以及一些有用的语句,您可以看到它的实际效果:asyncio.sleepgatherprint
from asyncio import create_task, gather, sleep, run
async def process(index: int):
    await sleep(.5)
    print('ok:', index)
async def create_tasks_then_gather():
    tasks = [create_task(process(item)) for item in range(5)]
    print("tasks scheduled")
    await sleep(2)  # <-- because of this `await` the tasks may begin to execute
    print("now gathering tasks")
    await gather(*tasks)
    print("gathered tasks")
async def create_coroutines_then_gather():
    coroutines = [process(item) for item in range(5)]
    print("coroutines created")
    await sleep(2)  # <-- despite this, the coroutines will not begin execution
    print("now gathering coroutines")
    await gather(*coroutines)
    print("gathered coroutines")
run(create_tasks_then_gather())
run(create_coroutines_then_gather())
输出:
tasks scheduled
ok: 0
ok: 1
ok: 2
ok: 3
ok: 4
now gathering tasks
gathered tasks
coroutines created
now gathering coroutines
ok: 0
ok: 1
ok: 2
ok: 3
ok: 4
gathered coroutines
正如你所看到的,in create_tasks_then_gatherbodyprocess是在调用之前执行的,而gatherin create_coroutines_then_gatherit是在调用之后执行的。
所以说有没有用,create_task要根据情况而定。如果您只关心并发执行并在代码中的特定点等待的协程,则调用create_task. 如果您想安排它们,然后继续做其他事情,而它们可能会也可能不会在后台做自己的事情,那么使用 是有意义的create_task。
然而,要记住的一件重要的事情是,您只能确保您计划的任务实际上完全执行(如果您在某个时刻执行了 await它们)。这就是为什么你仍然应该让 await gather他们(或同等的人)真正等待他们最终完成。
| 归档时间: | 
 | 
| 查看次数: | 2014 次 | 
| 最近记录: |