由于 Python 中的協程是運行在一條執行緒中通過訊息佇列調控的,如果運行的執行緒堵塞了那么就會造成訊息佇列阻塞,為了避免這種情況的發生我們需要區分 IO 密集型任務和 CUP 密集型任務,在 IO 密集型任務中,協程發生阻塞后會在訊息佇列中掛起轉而執行其它協程,而如果是 CUP 密集型任務則需要新開辟執行緒并放入執行以避免阻塞當前執行緒,
1 """ 2 協程中 IO 密集型任務和 CPU 密集型任務的區別: 3 4 協程碰到阻塞 IO 后會掛起繼續執行下一個任務,在 IO 結束后恢復運行, 5 而 CPU 密集型任務會阻塞整條訊息佇列(因為協程都是在一條執行緒里運行的),后果就是異步變成了同步, 6 7 IO 密集型任務舉例:請求網路(aiohttp)、讀寫檔案(aiofiles)、操作資料庫等,需要用到第三方庫 8 CPU 密集型任務舉例:決議網頁、數值計算等, 9 10 碰到 CUP 密集型任務為了防止佇列阻塞,需要用到執行緒池,aio提供了相應的介面,可見官方檔案, 11 """ 12 import asyncio 13 import time 14 15 async def work(n): 16 print(f'{n} is working.') # 這里會同時列印三條資訊 17 18 await asyncio.sleep(1) # 模擬 IO 19 20 print(f'{n} is awaked') # 這里只會列印單條資訊,因為下方是 CUP 密集型任務,會阻塞訊息佇列 21 22 s = 0 23 for i in range(1000000): # 模擬 CPU 密集型任務 24 s += i 25 26 print(f'{n} is done.') 27 28 return s 29 30 31 async def main(): 32 st = time.time() 33 tasks = [asyncio.create_task(work(i)) for i in range(3)] # 創建 3 個協程 34 35 await asyncio.gather(*tasks) # 并發啟動任務并等待任務結束 36 37 # 取消任務 38 for task in tasks: 39 task.cancel() 40 41 await asyncio.gather(*task, return_exceptions=True) 42 43 print('Done {:.2f}'.format(time.time()-st)) 44 45 46 if __name__ == '__main__': 47 asyncio.run(main())
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/69454.html
標籤:Python
上一篇:【python】字典
下一篇:re模塊
