python——asyncio模块实现协程、异步编程(二)

六】协程并发

定义tasks时可以设置多个ensure,也可以像多线程那样用append方法实现

[python] view plain copy

  1. tasks = [  
  2.     asyncio.ensure_future(coroutine1),  
  3.     asyncio.ensure_future(coroutine2),  
  4.     asyncio.ensure_future(coroutine3)  
  5. ]  
  6.   
  7. for i in range(4, 6):    
  8.     tasks.append(asyncio.ensure_future(do_some_work(i)))  


 

当遇到阻塞时可以使用await让其他协程继续工作

例如:

[python] view plain copy

  1. import asyncio  
  2. import time  
  3. now = lambda: time.time()  
  4.    
  5. async def do_some_work(x):  
  6.     print('Waiting: ', x)  
  7.    
  8.     await asyncio.sleep(x)  
  9.     return 'Done after {}s'.format(x)  
  10.    
  11. coroutine1 = do_some_work(1)  
  12. coroutine2 = do_some_work(2)  
  13. coroutine3 = do_some_work(3)   
  14.   
  15. tasks = [  
  16.     asyncio.ensure_future(coroutine1),  
  17.     asyncio.ensure_future(coroutine2),  
  18.     asyncio.ensure_future(coroutine3)  
  19. ]  
  20.   
  21. for i in range(4, 6):    
  22.     tasks.append(asyncio.ensure_future(do_some_work(i)))  
  23.    
  24. loop = asyncio.get_event_loop()  
  25.   
  26. start = now()  
  27. loop.run_until_complete(asyncio.wait(tasks))  
  28.    
  29. for task in tasks:  
  30.     print('Task ret: ', task.result())  
  31.    
  32. print('TIME: ', now() - start)  


通过运行时间可以看出aysncio实现了并发。asyncio.wait(tasks) 也可以使用 asyncio.gather(*tasks) ,前者接受一个task列表,后者接收一堆task。

【七】协程嵌套

使用async可以定义协程,协程用于耗时的io操作,我们也可以封装更多的io操作过程,这样就实现了嵌套的协程,即一个协程中await了另外一个协程,如此连接起来。

例如:

[python] view plain copy

  1. import asyncio  
  2. import time  
  3. now = lambda: time.time()  
  4. async def do_some_work(x):  
  5.     print('Waiting: ', x)  
  6.    
  7.     await asyncio.sleep(x)  
  8.     return 'Done after {}s'.format(x)  
  9.    
  10. async def main():  
  11.     coroutine1 = do_some_work(1)  
  12.     coroutine2 = do_some_work(2)  
  13.     coroutine3 = do_some_work(4)  
  14.    
  15.     tasks = [  
  16.         asyncio.ensure_future(coroutine1),  
  17.         asyncio.ensure_future(coroutine2),  
  18.         asyncio.ensure_future(coroutine3)  
  19.     ]  
  20.    
  21.     dones, pendings = await asyncio.wait(tasks)  
  22.    
  23.     for task in dones:  
  24.         print('Task ret: ', task.result())  
  25.    
  26. start = now()  
  27.    
  28. loop = asyncio.get_event_loop()  
  29. loop.run_until_complete(main())  
  30.    
  31. print('TIME: ', now() - start)  


 

如果使用的是 asyncio.gather创建协程对象,那么await的返回值就是协程运行的结果。

[python] view plain copy

  1. #dones, pendings = await asyncio.wait(tasks)  
  2.     #for task in dones:  
  3.     #print('Task ret: ', task.result())  
  4. results = await asyncio.gather(*tasks)  
  5. for result in results:  
  6.     print('Task ret: ', result)  


 

不在main协程函数里处理结果,直接返回await的内容,那么最外层的run_until_complete将会返回main协程的结果。

[python] view plain copy

  1. import asyncio  
  2. import time  
  3. now = lambda: time.time()  
  4. async def do_some_work(x):  
  5.     print('Waiting: ', x)  
  6.    
  7.     await asyncio.sleep(x)  
  8.     return 'Done after {}s'.format(x)  
  9.    
  10. async def main():  
  11.     coroutine1 = do_some_work(1)  
  12.     coroutine2 = do_some_work(2)  
  13.     coroutine3 = do_some_work(4)  
  14.    
  15.     tasks = [  
  16.         asyncio.ensure_future(coroutine1),  
  17.         asyncio.ensure_future(coroutine2),  
  18.         asyncio.ensure_future(coroutine3)  
  19.     ]  
  20.    
  21.     return await asyncio.gather(*tasks)  
  22.    
  23. start = now()  
  24. loop = asyncio.get_event_loop()  
  25. results = loop.run_until_complete(main())  
  26. for result in results:  
  27.     print('Task ret: ', result)  
  28.    
  29. print('TIME: ', now() - start)  


 

或者返回使用asyncio.wait方式挂起协程。

[python] view plain copy

  1. import asyncio  
  2. import time  
  3. now = lambda: time.time()  
  4. async def do_some_work(x):  
  5.     print('Waiting: ', x)  
  6.    
  7.     await asyncio.sleep(x)  
  8.     return 'Done after {}s'.format(x)  
  9.    
  10. async def main():  
  11.     coroutine1 = do_some_work(1)  
  12.     coroutine2 = do_some_work(2)  
  13.     coroutine3 = do_some_work(4)  
  14.    
  15.     tasks = [  
  16.         asyncio.ensure_future(coroutine1),  
  17.         asyncio.ensure_future(coroutine2),  
  18.         asyncio.ensure_future(coroutine3)  
  19.     ]  
  20.    
  21.     return await asyncio.wait(tasks)  
  22.    
  23. start = now()  
  24.    
  25. loop = asyncio.get_event_loop()  
  26. done, pending = loop.run_until_complete(main())  
  27.    
  28. for task in done:  
  29.     print('Task ret: ', task.result())  
  30.    
  31. print('TIME: ', now() - start)  


也可以使用asyncio的as_completed方法

[python] view plain copy

  1. import asyncio  
  2. import time  
  3. now = lambda: time.time()  
  4. async def do_some_work(x):  
  5.     print('Waiting: ', x)  
  6.    
  7.     await asyncio.sleep(x)  
  8.     return 'Done after {}s'.format(x)  
  9.    
  10. async def main():  
  11.     coroutine1 = do_some_work(1)  
  12.     coroutine2 = do_some_work(2)  
  13.     coroutine3 = do_some_work(4)  
  14.    
  15.     tasks = [  
  16.         asyncio.ensure_future(coroutine1),  
  17.         asyncio.ensure_future(coroutine2),  
  18.         asyncio.ensure_future(coroutine3)  
  19.     ]  
  20.     for task in asyncio.as_completed(tasks):  
  21.         result = await task  
  22.         print('Task ret: {}'.format(result))  
  23.    
  24. start = now()  
  25.    
  26. loop = asyncio.get_event_loop()  
  27. done = loop.run_until_complete(main())  
  28. print('TIME: ', now() - start)  

猜你喜欢

转载自blog.csdn.net/liujiandu101/article/details/81136438
今日推荐