這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
參考廖雪峰非同步I/O篇
一、為什麼使用非同步IO
- CPU的速度遠遠快於磁碟、網路等IO(我們要解決的問題是CPU高速執行能力和IO裝置的龜速嚴重不匹配)
- 同步IO模型:一個IO操作就阻塞了當前線程,導致其他代碼無法執行,所以我們必須使用多線程或者多進程來並發執行代碼
- 但系統切換線程的開銷也很大,所以,一旦線程數量過多,CPU的時間就花線上程切換上了,真正運行代碼的時間就少了,結果導致效能嚴重下降
- 非同步IO模型:當代碼需要執行一個耗時的IO操作時,它只發出IO指令,並不等待IO結果,然後就去執行其他代碼了。一段時間後,當IO返回結果時,再通知CPU進行處理。
二、非同步IO模型
非同步IO模型需要一個訊息迴圈,在訊息迴圈中,主線程不斷地重複“讀取訊息-處理訊息”這一過程:
loop = get_event_loop()while True: event = loop.get_event() process_event(event)
訊息模型其實早在應用在傳統型應用程式中了。一個GUI程式的主線程就負責不停地讀取訊息並處理訊息。所有的鍵盤、滑鼠等訊息都被發送到GUI程式的訊息佇列中,然後由GUI程式的主線程處理。
當遇到IO操作時,代碼只負責發出IO請求,不等待IO結果,然後直接結束本輪訊息處理,進入下一輪訊息處理過程。當IO操作完成後,將收到一條“IO完成”的訊息,處理該訊息時就可以直接擷取IO操作結果。
三、真·為什麼使用非同步IO
在“發出IO請求”到收到“IO完成”的這段時間裡,同步IO模型下,主線程只能掛起,但非同步IO模型下,主線程並沒有休息,而是在訊息迴圈中繼續處理其他訊息。這樣,在非同步IO模型下,一個線程就可以同時處理多個IO請求,並且沒有切換線程的操作。對於大多數IO密集型的應用程式,使用非同步IO將大大提升系統的多任務處理能力。
四、協程Coroutine
Donald Knuth:子程式就是協程的一種特例
協程看上去也是子程式,但執行過程中,在子程式內部可中斷,然後轉而執行別的子程式,在適當的時候再返回來接著執行
a)協程vs線程
- 最大的優勢就是協程極高的執行效率。因為子程式切換不是線程切換,而是由程式自身控制,因此,沒有線程切換的開銷,和多線程比,線程數量越多,協程的效能優勢就越明顯。
- 第二大優勢就是不需要多線程的鎖機制,因為只有一個線程,也不存在同時寫變數衝突,在協程中控制共用資源不加鎖,只需要判斷狀態就好了,所以執行效率比多線程高很多。
- 因為協程是一個線程執行,那怎麼利用多核CPU呢?最簡單的方法是多進程+協程,既充分利用多核,又充分發揮協程的高效率,可獲得極高的效能。
b)python協程實現
don·t care,不如直接golang