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)  

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章