问题描述
我已经阅读了许多关于 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 1
和 case 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 1
和 case 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 中最简单的异步/等待示例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!