Python 中最简单的异步/等待示例 [英] Simplest async/await example possible in Python

查看:33
本文介绍了Python 中最简单的异步/等待示例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经阅读了许多关于 Python 3.5+ 中 asyncio/async/await 的示例、博客文章、问题/答案,其中很多是复杂,我发现的最简单的可能是这个.
它仍然使用 ensure_future,并且出于学习 Python 异步编程的目的,我希望看到一个更简单的示例,以及所需的最小工具是什么基本的异步/等待示例.

I've read many examples, blog posts, questions/answers about asyncio / async / await in Python 3.5+, many were complex, the simplest I found was probably this one.
Still it uses ensure_future, and for learning purposes about asynchronous programming in Python, I would like to see an even more minimal example, and what are the minimal tools necessary to do a basic async / await example.

问题:是否可以给出一个简单的例子来展示async/await 是如何工作的,只使用这两个关键字 + 代码来运行异步循环 + 其他 Python 代码但没有其他 asyncio 函数?

Question: is it possible to give a simple example showing how async / await works, by using only these two keywords + code to run the async loop + other Python code but no other asyncio functions?

例如:像这样:

import asyncio

async def async_foo():
    print("async_foo started")
    await asyncio.sleep(5)
    print("async_foo done")

async def main():
    asyncio.ensure_future(async_foo())  # fire and forget async_foo()
    print('Do some actions 1')
    await asyncio.sleep(5)
    print('Do some actions 2')

loop = asyncio.get_event_loop()
loop.run_until_complete(main())

但没有 ensure_future,并且仍然演示了 await/async 的工作原理.

but without ensure_future, and still demonstrates how await / async works.

推荐答案

为了回答您的问题,我将针对同一问题提供 3 种不同的解决方案.

To answer your questions I will provide 3 different solutions to the same problem.

案例1:只是普通的python

import time

def sleep():
    print(f'Time: {time.time() - start:.2f}')
    time.sleep(1)

def sum(name, numbers):
    total = 0
    for number in numbers:
        print(f'Task {name}: Computing {total}+{number}')
        sleep()
        total += number
    print(f'Task {name}: Sum = {total}
')

start = time.time()
tasks = [
    sum("A", [1, 2]),
    sum("B", [1, 2, 3]),
]
end = time.time()
print(f'Time: {end-start:.2f} sec')

输出:

Task A: Computing 0+1
Time: 0.00
Task A: Computing 1+2
Time: 1.00
Task A: Sum = 3

Task B: Computing 0+1
Time: 2.01
Task B: Computing 1+2
Time: 3.01
Task B: Computing 3+3
Time: 4.01
Task B: Sum = 6

Time: 5.02 sec

情况 2:async/await 做错了

import asyncio
import time

async def sleep():
    print(f'Time: {time.time() - start:.2f}')
    time.sleep(1)

async def sum(name, numbers):
    total = 0
    for number in numbers:
        print(f'Task {name}: Computing {total}+{number}')
        await sleep()
        total += number
    print(f'Task {name}: Sum = {total}
')

start = time.time()

loop = asyncio.get_event_loop()
tasks = [
    loop.create_task(sum("A", [1, 2])),
    loop.create_task(sum("B", [1, 2, 3])),
]
loop.run_until_complete(asyncio.wait(tasks))
loop.close()

end = time.time()
print(f'Time: {end-start:.2f} sec')

输出:

Task A: Computing 0+1
Time: 0.00
Task A: Computing 1+2
Time: 1.00
Task A: Sum = 3

Task B: Computing 0+1
Time: 2.01
Task B: Computing 1+2
Time: 3.01
Task B: Computing 3+3
Time: 4.01
Task B: Sum = 6

Time: 5.01 sec

case 3: async/await done right(除了sleep函数外,与case 2相同)

case 3: async/await done right (same as case 2 except the sleep function)

import asyncio
import time

async def sleep():
    print(f'Time: {time.time() - start:.2f}')
    await asyncio.sleep(1)

async def sum(name, numbers):
    total = 0
    for number in numbers:
        print(f'Task {name}: Computing {total}+{number}')
        await sleep()
        total += number
    print(f'Task {name}: Sum = {total}
')

start = time.time()

loop = asyncio.get_event_loop()
tasks = [
    loop.create_task(sum("A", [1, 2])),
    loop.create_task(sum("B", [1, 2, 3])),
]
loop.run_until_complete(asyncio.wait(tasks))
loop.close()

end = time.time()
print(f'Time: {end-start:.2f} sec')

输出:

Task A: Computing 0+1
Time: 0.00
Task B: Computing 0+1
Time: 0.00
Task A: Computing 1+2
Time: 1.00
Task B: Computing 1+2
Time: 1.00
Task A: Sum = 3

Task B: Computing 3+3
Time: 2.00
Task B: Sum = 6

Time: 3.01 sec

case 1case 2 给出相同的 5 seconds,而 case 3 只是 3秒.所以 async/await 正确完成 更快.​​

case 1 with case 2 give the same 5 seconds, whereas case 3 just 3 seconds. So the async/await done right is faster.

差异的原因在于sleep函数的实现.

The reason for the difference is within the implementation of sleep function.

# case 1
def sleep():
    print(f'Time: {time.time() - start:.2f}')
    time.sleep(1)

# case 2
async def sleep():
    print(f'Time: {time.time() - start:.2f}')
    time.sleep(1)

# case 3
async def sleep():
    print(f'Time: {time.time() - start:.2f}')
    await asyncio.sleep(1)

case 1case 2 中的

sleep 函数是相同的".他们在不让其他人使用资源的情况下睡觉".而 case 3 允许在它休眠时访问资源.

sleep function in case 1 and case 2 are the "same". They "sleep" without allowing others to use the resources. Whereas case 3 allows access to the resources when it is asleep.

case 2 中,我们将async 添加到普通函数中.然而,事件循环将不间断地运行它.为什么?因为我们没有告诉循环在哪里可以中断你的函数来运行另一个任务.

In case 2 we added async to the normal function. However the event loop will run it without interruption. Why? Because we didn't tell where the loop is allowed to interrupt your function to run another task.

case 3中,我们告诉事件循环在何处中断函数以运行另一个任务.具体在哪里?

In case 3 we told the event loop exactly where to interrupt the function to run another task. Where exactly?

# case 3
async def sleep():
    print(f'Time: {time.time() - start:.2f}')
    await asyncio.sleep(1) # <-- Right here!

有关此阅读的更多信息此处

2020 年 5 月 2 日更新

考虑阅读

这篇关于Python 中最简单的异步/等待示例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆