简体   繁体   English

Python:如果不使用 asyncio.gather(),为什么要使用 AsyncIO?

[英]Python: why use AsyncIO if not with asyncio.gather()?

I recently started looking into asynchronous programming in Python.我最近开始研究 Python 中的异步编程。 Let's say we want to run a function asynchronously, an example below:假设我们想异步运行一个函数,下面是一个例子:

async def print_i_async(no):
    print("Async: Preparing print of " + str(no))
    await asyncio.sleep(1)
    print(str(no))

async def main_async(no):
    await asyncio.gather(*(print_i_async(i) for i in range(no)))

asyncio.run(main_async(no))

This will as expected work asynchronously.这将按预期异步工作。 It's not clear to me, however, why would we use asynchronous functions if not with asyncio.gather() .然而,我不清楚,如果不使用asyncio.gather() ,我们为什么要使用异步函数。 For example:例如:

def print_i_serial(no):
    print("Serial: Preparing print of " + str(no))
    time.sleep(1)
    print(str(no))

for i in range(5):
    print_i_serial(i)

for i in range(5):
    asyncio.run(print_i_async(i))

These two functions produce the same result.这两个函数产生相同的结果。 Am I missing something?我错过了什么吗? Is there any reason we would use an async def if we don't use asyncio.gather() , given this is how we actually get asynchronous results?如果我们不使用asyncio.gather() ,我们是否有任何理由使用async def ,因为这是我们实际获得异步结果的方式?

There are many reasons to use asyncio besides gather .除了gather之外,还有很多使用asyncio原因。

What you are really asking is: are there more ways to create concurrent executions besides gather ?您真正要问的是:除了gather之外,还有更多方法可以创建并发执行吗?

To that the answer is yes.答案是肯定的。

Yes, gather is one of the simplest and most straightforward examples for creating concurrency with asyncio , but it's not limited to gather .是的, gather是使用asyncio创建并发性的最简单、最直接的示例asyncio ,但它不仅限于gather What gather does is creating a bunch of awaitables (if needed, for example coroutines are wrapped in a task) to wait for and return the result once all the futures are ready (and a bunch of other stuff such as propagating cancellation). gather所做的是创建一堆等待对象(如果需要,例如协程被包装在一个任务中)以等待并在所有期货准备好后返回结果(以及一堆其他东西,例如传播取消)。

Let's examine just two more examples of ways to achieve concurrency:让我们再看两个实现并发的方法的例子:

  1. as_completed - similarly to gather , you send in a bunch of awaitables, but instead of waiting for all of them to be ready, this method returns you the futures as they become ready, unordered. as_completed - 与gather类似,您发送一堆可等待对象,但不是等待所有等待对象都准备好,此方法会在它们准备好、无序时返回给您。
  2. Another example is to create tasks yourself, eg with event_loop.create_task() .另一个例子是自己创建任务,例如使用event_loop.create_task() This will allow you to create a task that will run on the event loop, which you can later await .这将允许您创建一个将在事件循环上运行的任务,您可以稍后await In the meantime (until you await the task) you can continue running other code, and basically achieve concurrency (note the task will not run straightaway, but only when you yield control back to the event loop, and it handles the task).同时(直到您await任务)您可以继续运行其他代码,并基本上实现并发(注意任务不会立即运行,但只有当您将控制权交还给事件循环并处理任务时)。

There are many more ways to achieve concurrency.实现并发的方法还有很多。 You can start with these examples (the 2nd one is actually a general way you can use to create lots of different concurrent "topologies" of executions).您可以从这些示例开始(第二个示例实际上是您可以用来创建许多不同的并发执行“拓扑”的通用方法)。

You can start by reading https://docs.python.org/3/library/asyncio-task.html您可以先阅读https://docs.python.org/3/library/asyncio-task.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM