我已经阅读了很多关于 Python 3.5+ 中的 asyncio
/async
/await
的示例、博客文章、问题/答案,很多都是复杂,我发现最简单的可能是 this one .
它仍然使用 ensure_future
,并且出于学习 Python 异步编程的目的,我希望看到一个更简单的示例,以及必要的最小工具是什么基本异步/等待示例。
问题:是否可以给出一个简单的例子来说明async
/await
是如何工作的,只使用这两个关键字+代码来运行异步循环 + 其他 Python 代码但没有其他 asyncio
函数?
例子:像这样:
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 是如何工作的。
最佳答案
为了回答您的问题,我将针对同一问题提供 3 种不同的解决方案。
案例 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}\n')
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}\n')
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
案例 3:async/await 正确完成
除了 sleep
函数外,与情况 2 相同:
async def sleep():
print(f'Time: {time.time() - start:.2f}')
await asyncio.sleep(1)
输出:
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
案例 1 和案例 2 给出了相同的 5 秒,而案例 3 只给出了 3 秒。因此,正确完成 async/await 速度更快。
差异的原因在于 sleep
函数的实现。
# case 1
def sleep():
...
time.sleep(1)
# case 2
async def sleep():
...
time.sleep(1)
# case 3
async def sleep():
...
await asyncio.sleep(1)
在情况 1 和情况 2 中,它们是“相同的”: 他们在不允许其他人使用资源的情况下“ sleep ”。 而在情况 3 中,它允许在 sleep 时访问资源。
在案例 2 中,我们将 async
添加到普通函数中。然而,事件循环将不间断地运行。
为什么?因为我们没有说明允许循环在哪里中断您的函数以运行另一个任务。
在案例 3 中,我们告诉事件循环在何处中断函数以运行另一个任务。具体在哪里?就在这里!
await asyncio.sleep(1)
有关此阅读的更多信息 here
2020 年 5 月 2 日更新
考虑阅读
关于python - Python 中最简单的异步/等待示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50757497/