在io程式設計一節中,我們已經知道,cpu的速度遠遠快於磁碟、網路等io。在乙個執行緒中,cpu執行**的速度極快,然而,一旦遇到io操作,如讀寫檔案、傳送網路資料時,就需要等待io操作完成,才能繼續進行下一步操作。這種情況稱為同步io。
在io操作的過程中,當前執行緒被掛起,而其他需要cpu執行的**就無法被當前執行緒執行了。
因為乙個io操作就阻塞了當前執行緒,導致其他**無法執行,所以我們必須使用多執行緒或者多程序來併發執行**,為多個使用者服務。每個使用者都會分配乙個執行緒,如果遇到io導致執行緒被掛起,其他使用者的執行緒不受影響。
由於我們要解決的問題是cpu高速執行能力和io裝置的龜速嚴重不匹配,多執行緒和多程序只是解決這一問題的一種方法。
另一種解決io問題的方法是非同步io。當**需要執行乙個耗時的io操作時,它只發出io指令,並不等待io結果,然後就去執行其他**了。一段時間後,當io返回結果時,再通知cpu進行處理。
可以想象如果按普通順序寫出的**實際上是沒法完成非同步io的:
do_some_code()
f = open('/path/to/file', 'r')
r = f.read() # <== 執行緒停在此處等待io操作結果
# io操作完成後執行緒才能繼續執行:
do_some_code(r)
所以,同步io模型的**是無法實現非同步io模型的。
非同步io模型需要乙個訊息迴圈,在訊息迴圈中,主線程不斷地重複「讀取訊息-處理訊息」這一過程:
loop = get_event_loop()
while true:
event = loop.get_event()
process_event(event)
訊息模型其實早在應用在桌面應用程式中了。乙個gui程式的主線程就負責不停地讀取訊息並處理訊息。所有的鍵盤、滑鼠等訊息都被傳送到gui程式的訊息佇列中,然後由gui程式的主線程處理。
由於gui執行緒處理鍵盤、滑鼠等訊息的速度非常快,所以使用者感覺不到延遲。某些時候,gui執行緒在乙個訊息處理的過程中遇到問題導致一次訊息處理時間過長,此時,使用者會感覺到整個gui程式停止響應了,敲鍵盤、點滑鼠都沒有反應。這種情況說明在訊息模型中,處理乙個訊息必須非常迅速,否則,主線程將無法及時處理訊息佇列中的其他訊息,導致程式看上去停止響應。
訊息模型是如何解決同步io必須等待io操作這一問題的呢?當遇到io操作時,**只負責發出io請求,不等待io結果,然後直接結束本輪訊息處理,進入下一輪訊息處理過程。當io操作完成後,將收到一條「io完成」的訊息,處理該訊息時就可以直接獲取io操作結果。
在「發出io請求」到收到「io完成」的這段時間裡,同步io模型下,主線程只能掛起,但非同步io模型下,主線程並沒有休息,而是在訊息迴圈中繼續處理其他訊息。這樣,在非同步io模型下,乙個執行緒就可以同時處理多個io請求,並且沒有切換執行緒的操作。對於大多數io密集型的應用程式,使用非同步io將大大提公升系統的多工處理能力。
Python學習 非同步IO
在io程式設計一節中,我們已經知道,cpu的速度遠遠快於磁碟 網路等io。在乙個執行緒中,cpu執行 的速度極快,然而,一旦遇到io操作,如讀寫檔案 傳送網路資料時 就需要等待io操作完成,才能繼續進行下一步操作。這種情況稱為同步io 在io操作的過程中,當前執行緒被掛起,而其他需要cpu執行的 就...
python之非同步IO
我們知道,cpu的速度遠遠快於磁碟 網路等io。在乙個執行緒中,cpu執行 的速度極快,然而,一旦遇到io操作,如讀寫檔案 傳送網路資料時,就需要等待io操作完成,才能繼續進行下一步操作。這種情況稱為同步io。在io操作的過程中,當前執行緒被掛起,而其他需要cpu執行的 就無法被當前執行緒執行了。因...
python非同步io讀檔案 python之非同步IO
我們知道,cpu的速度遠遠快於磁碟 網路等io。在乙個執行緒中,cpu執行 的速度極快,然而,一旦遇到io操作,如讀寫檔案 傳送網路資料時,就需要等待io操作完成,才能繼續進行下一步操作。這種情況稱為同步io。在io操作的過程中,當前執行緒被掛起,而其他需要cpu執行的 就無法被當前執行緒執行了。因...