python2异步编程,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 if an even more minimal example is possible (i.e. what are the minimum tools necessary to do a basic async / await example).

Question: for learning purposes about asynchronous programming in Python, is it possible to give a simple example showing how async / await works, by using only these two keywords + asyncio.get_event_loop() + run_until_complete + other Python code but no other asyncio functions?

Example: something like this:

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())

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

解决方案

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

case 1: just normal 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')

output:

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

case 2: async/await done wrong

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')

output:

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 (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}\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')

output:

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 with case 2 give the same 5 seconds, whereas case 3 just 3 seconds. So the async/await done right is faster.

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)

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.

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.

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) #

More on this read here

Update 02/May/2020

Consider reading

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值