Python 協程中的 IO 密集型任務和 CPU 密集型任務簡單測試


由於 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())

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM