1. 做家务
我们用上面做家务的例子来用协程实现一下:
import timeimport asyncioasync 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 ClothesB1: I have prepared clothes(*)A: Boil WaterA1: I have prepared water(*)C: I have mop the floor clean(*)A2: Water has boiled upA3: Water has been poured into the bottle(*)B2: Clothes have been washed cleanB3: Clothes have been hanged up(*)cost time: 25.004190921783447
显然这和我们预期的结果一样,但实际上我们调整一下 tasks 里面元素的位置,就会发现出来的结果会有所不同,这是因为程序在 CPU 空闲时会随机看哪个任务可以上,就开启哪个任务。
为了得到最理想的结果的话,可以简单做一下改写:
import timeimport asyncioasync 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)
这样调整之后,每次运行之后的结果就都和我们的预期一致了,但显然这种人工调整的方式在实际场景中并不适用。
