Python Asyncio.gather 与 asyncio.wait
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/42231161/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Asyncio.gather vs asyncio.wait
提问by Claude
asyncio.gather
and asyncio.wait
seem to have similar uses: I have a bunch of async things that I want to execute/wait for (not necessarily waiting for one to finish before the next one starts). They use a different syntax, and differ in some details, but it seems very un-pythonic to me to have 2 functions that have such a huge overlap in functionality. What am I missing?
asyncio.gather
并且asyncio.wait
似乎有类似的用途:我有一堆异步的东西要执行/等待(不一定要在下一个开始之前等待一个完成)。它们使用不同的语法,并且在一些细节上有所不同,但对我来说,拥有 2 个在功能上有如此巨大重叠的函数似乎非常不符合 Python 风格。我错过了什么?
回答by Udi
Although similar in general cases ("run and get results for many tasks"), each function has some specific functionality for other cases:
尽管在一般情况下类似(“运行并获得许多任务的结果”),但每个函数对于其他情况都有一些特定的功能:
asyncio.gather()
asyncio.gather()
Returns a Future instance, allowing high level grouping of tasks:
返回一个 Future 实例,允许对任务进行高级分组:
import asyncio
from pprint import pprint
import random
async def coro(tag):
print(">", tag)
await asyncio.sleep(random.uniform(1, 3))
print("<", tag)
return tag
loop = asyncio.get_event_loop()
group1 = asyncio.gather(*[coro("group 1.{}".format(i)) for i in range(1, 6)])
group2 = asyncio.gather(*[coro("group 2.{}".format(i)) for i in range(1, 4)])
group3 = asyncio.gather(*[coro("group 3.{}".format(i)) for i in range(1, 10)])
all_groups = asyncio.gather(group1, group2, group3)
results = loop.run_until_complete(all_groups)
loop.close()
pprint(results)
All tasks in a group can be cancelled by calling group2.cancel()
or even all_groups.cancel()
. See also .gather(..., return_exceptions=True)
,
一个组中的所有任务都可以通过调用group2.cancel()
或取消all_groups.cancel()
。另见.gather(..., return_exceptions=True)
,
asyncio.wait()
asyncio.wait()
Supports waiting to be stopped after the first task is done, or after a specified timeout, allowing lower level precision of operations:
支持在第一个任务完成后或指定超时后等待停止,允许较低级别的操作精度:
import asyncio
import random
async def coro(tag):
print(">", tag)
await asyncio.sleep(random.uniform(0.5, 5))
print("<", tag)
return tag
loop = asyncio.get_event_loop()
tasks = [coro(i) for i in range(1, 11)]
print("Get first result:")
finished, unfinished = loop.run_until_complete(
asyncio.wait(tasks, return_when=asyncio.FIRST_COMPLETED))
for task in finished:
print(task.result())
print("unfinished:", len(unfinished))
print("Get more results in 2 seconds:")
finished2, unfinished2 = loop.run_until_complete(
asyncio.wait(unfinished, timeout=2))
for task in finished2:
print(task.result())
print("unfinished2:", len(unfinished2))
print("Get all other results:")
finished3, unfinished3 = loop.run_until_complete(asyncio.wait(unfinished2))
for task in finished3:
print(task.result())
loop.close()
回答by ospider
asyncio.wait
is more low level than asyncio.gather
.
asyncio.wait
比 低asyncio.gather
。
As the name suggests, asyncio.gather
mainly focuses on gathering the results. it waits on a bunch of futures and return their results in a given order.
顾名思义,asyncio.gather
主要侧重于收集结果。它等待一堆期货并按给定顺序返回它们的结果。
asyncio.wait
just waits on the futures. and instead of giving you the results directly, it gives done and pending tasks. you have to mannually collect the values.
asyncio.wait
只等期货。它不会直接为您提供结果,而是提供已完成和待处理的任务。您必须手动收集值。
Moreover, you could specify to wait for all futures to finish or the just the first one with wait
.
此外,您可以指定等待所有期货完成或仅等待第一个带有wait
.
回答by Johny Ebanat
I also noticed that you can provide a group of coroutines in wait() by simply specifying the list:
我还注意到你可以通过简单地指定列表在 wait() 中提供一组协程:
result=loop.run_until_complete(asyncio.wait([
say('first hello', 2),
say('second hello', 1),
say('third hello', 4)
]))
Whereas grouping in gather() is done by just specifying multiple coroutines:
而在 gather() 中的分组只是通过指定多个协程来完成的:
result=loop.run_until_complete(asyncio.gather(
say('first hello', 2),
say('second hello', 1),
say('third hello', 4)
))