1. 做家务

我们用上面做家务的例子来用协程实现一下:

  1. import time
  2. import asyncio
  3. async def boil_water():
  4. print("A: Boil Water")
  5. time.sleep(2)
  6. print("A1: I have prepared water(*)")
  7. await asyncio.sleep(10)
  8. print("A2: Water has boiled up")
  9. time.sleep(3)
  10. print("A3: Water has been poured into the bottle(*)")
  11. async def wash_clothes():
  12. print("B: Wash Clothes")
  13. time.sleep(5)
  14. print("B1: I have prepared clothes(*)")
  15. await asyncio.sleep(15)
  16. print("B2: Clothes have been washed clean")
  17. time.sleep(5)
  18. print("B3: Clothes have been hanged up(*)")
  19. async def mop_floor():
  20. time.sleep(10)
  21. print("C: I have mop the floor clean(*)")
  22. loop = asyncio.get_event_loop()
  23. tasks = [boil_water(), wash_clothes(), mop_floor()]
  24. start = time.time()
  25. loop.run_until_complete(asyncio.wait(tasks))
  26. loop.close()
  27. end = time.time()
  28. print("cost time: ", end - start)

输出结果:

  1. B: Wash Clothes
  2. B1: I have prepared clothes(*)
  3. A: Boil Water
  4. A1: I have prepared water(*)
  5. C: I have mop the floor clean(*)
  6. A2: Water has boiled up
  7. A3: Water has been poured into the bottle(*)
  8. B2: Clothes have been washed clean
  9. B3: Clothes have been hanged up(*)
  10. cost time: 25.004190921783447

显然这和我们预期的结果一样,但实际上我们调整一下 tasks 里面元素的位置,就会发现出来的结果会有所不同,这是因为程序在 CPU 空闲时会随机看哪个任务可以上,就开启哪个任务。

为了得到最理想的结果的话,可以简单做一下改写:

  1. import time
  2. import asyncio
  3. async def boil_water():
  4. print("A: Boil Water")
  5. time.sleep(2)
  6. print("A1: I have prepared water(*)")
  7. await mop_floor()
  8. print("A2: Water has boiled up")
  9. time.sleep(3)
  10. print("A3: Water has been poured into the bottle(*)")
  11. async def wash_clothes():
  12. print("B: Wash Clothes")
  13. time.sleep(5)
  14. print("B1: I have prepared clothes(*)")
  15. await boil_water()
  16. print("B2: Clothes have been washed clean")
  17. time.sleep(5)
  18. print("B3: Clothes have been hanged up(*)")
  19. async def mop_floor():
  20. time.sleep(10)
  21. print("C: I have mop the floor clean(*)")
  22. loop = asyncio.get_event_loop()
  23. tasks = [
  24. loop.create_task(wash_clothes()),
  25. ]
  26. start = time.time()
  27. loop.run_until_complete(asyncio.wait(tasks))
  28. loop.close()
  29. end = time.time()
  30. print("cost time: ", end - start)

这样调整之后,每次运行之后的结果就都和我们的预期一致了,但显然这种人工调整的方式在实际场景中并不适用。