Asyncio 不是多線程或多進程,而是並行運行代碼。
JavaScript 中支持異步執行(浏覽器,Nodejs,Electron 等)。在早期版本中,他們只是使用回調功能在異步操作完成後運行其他功能。但是它在 JavaScript 中創建了回調問題,因此在過去的十年中的某個時候,它們實現了相同的異步等待界面,我們在Python 3.6+ 中具有。該界面在使用相同的並行IO 效率的序列執行中尋找用戶
import asyncioimport timedef write(msg): print(msg, flush=True)async def say1(): await asyncio.sleep(1) write("Hello from 1")async def say2(): await asyncio.sleep(1) write("Hello from 2") write("start")loop = asyncio.get_event_loop()loop.run_until_complete(asyncio.gather( say1(), say2()))write("exit")loop.close()
運行該代碼,可以看到 Hello from 1
運行 1 秒後運行 Hello from 2
:
$ python asyncoidemo2.py startHello from 1Hello from 2exit
當 run_until_complete
運行 say()
函數,解釋器會逐行執行該函數的內容。當碰到 await
之後,解釋器開始異步操作:這個操作為了循環將完成一些內部回調操作,這個回調操作是對開發人員隱藏的。但是現在,say1
開始後,它立即將控制返回到事件循環。所以,它啟動異步 sleep
和控制循環,然後循環實際上已經開始啟動 say2
函數。
當第一次異步 sleep
運行 1秒後,進入內部回調執行 say1
協程,下一個操作是打印 Hello from 1
。打印後,它再次返回到活動循環。同時,從第二次睡眠開始,循環獲得了有關完成第二次睡眠的事件。
所以接下來 Hello from 2
打印,然後第二種方法也返回。 run_until_complete(gather(l1,l2,l3))
將阻止所有 l1,l2,l3 Coroutines:
請注意,7 和 9 事件可能會交換 - 如果您多次運行代碼,您可能會注意到 Hello from 1
打印在 Hello from 2
之後。
event_loop 事件循環:程序開啟一個無限循環,把一些函數注冊到事件循環上,當滿足事件發生的時候,調用相應的協程函數
coroutine 協程:協程對象,指一個使用 async 關鍵字定義的函數,它的調用不會立即執行函數,而是會返回一個協程對象。協程對象需要注冊到事件循環,由事件循環調用。
task 任務:一個協程對象就是一個原生可以掛起的函數,任務則是對協程進一步封裝,其中包含了任務的各種狀態
future: 代表將來執行或沒有執行的任務的結果。它和 task 上沒有本質上的區別
async/await 關鍵字:python3.5 用於定義協程的關鍵字,async 定義一個協程,await 用於掛起阻塞的異步調用接口。
當您需要並行多個 CPU 操作時。協程僅用於 IO 操作,例如某些 HTTP 客戶端,例如 aiohttps
調用服務器。
CPU 計算操作,例如機器學習,在巨大的數列上循環,加快 CPU 運算。
Python中異步程序員工具套件中的最基本工具是新的關鍵字 async def
,它用於聲明異步的 coroutine 函數,其方式與定義正常同步函數的 def
相同。
當我們使用 asyncio 時,我們會使用單個過程線程同時執行所有任務。asyncio是一個整潔的概念,並且每個數據科學家至少應該知道要使代碼運行速度更快。了解該過程的良好工作知識也將幫助您了解即將到來的庫,例如 Fastapi,Aiohttp,Aiofiles,Puppeteer 等。