1. 做家务
我们用上面做家务的例子来用协程实现一下:
import time
import asyncio
async def boil_water():
print("A: Boil Water")
time.sleep(2)
print("A1: I have prepared water(*)")
await asyncio.sleep(10)
print("A2: Water has boiled up")
time.sleep(3)
print("A3: Water has been poured into the bottle(*)")
async def wash_clothes():
print("B: Wash Clothes")
time.sleep(5)
print("B1: I have prepared clothes(*)")
await asyncio.sleep(15)
print("B2: Clothes have been washed clean")
time.sleep(5)
print("B3: Clothes have been hanged up(*)")
async def mop_floor():
time.sleep(10)
print("C: I have mop the floor clean(*)")
loop = asyncio.get_event_loop()
tasks = [boil_water(), wash_clothes(), mop_floor()]
start = time.time()
loop.run_until_complete(asyncio.wait(tasks))
loop.close()
end = time.time()
print("cost time: ", end - start)
输出结果:
B: Wash Clothes
B1: I have prepared clothes(*)
A: Boil Water
A1: I have prepared water(*)
C: I have mop the floor clean(*)
A2: Water has boiled up
A3: Water has been poured into the bottle(*)
B2: Clothes have been washed clean
B3: Clothes have been hanged up(*)
cost time: 25.004190921783447
显然这和我们预期的结果一样,但实际上我们调整一下 tasks
里面元素的位置,就会发现出来的结果会有所不同,这是因为程序在 CPU 空闲时会随机看哪个任务可以上,就开启哪个任务。
为了得到最理想的结果的话,可以简单做一下改写:
import time
import asyncio
async def boil_water():
print("A: Boil Water")
time.sleep(2)
print("A1: I have prepared water(*)")
await mop_floor()
print("A2: Water has boiled up")
time.sleep(3)
print("A3: Water has been poured into the bottle(*)")
async def wash_clothes():
print("B: Wash Clothes")
time.sleep(5)
print("B1: I have prepared clothes(*)")
await boil_water()
print("B2: Clothes have been washed clean")
time.sleep(5)
print("B3: Clothes have been hanged up(*)")
async def mop_floor():
time.sleep(10)
print("C: I have mop the floor clean(*)")
loop = asyncio.get_event_loop()
tasks = [
loop.create_task(wash_clothes()),
]
start = time.time()
loop.run_until_complete(asyncio.wait(tasks))
loop.close()
end = time.time()
print("cost time: ", end - start)
这样调整之后,每次运行之后的结果就都和我们的预期一致了,但显然这种人工调整的方式在实际场景中并不适用。