同步和異步
同步和異步是用戶線程與內核交互的方式,關注的是消息通知機制,是如何通知調用者.
同步: synchronous
調用發出之后, 不會立即返回,一旦返回即是最終結果
異步:asynchronous
調用發出之后, 被調用方立即返回消息, 但返回的并非最終結果,被調用者通過狀態通知機制來通知調用者,或通過回調函數來處理結果
阻塞和非阻塞
阻塞和非阻塞是用戶線程調用內核IO操作的方式,關注的是調用者等待被調用者返回調用結果時的狀態(即中間過程)
阻塞:block
調用結果返回之前,調用者會被掛起,可能轉為不可中斷睡眠,調用者只有在等到返回結果之后才會繼續處理新的請求.
非阻塞: nonblock
調用者在結果返回之前,不會被掛起,即調用不會被阻塞調用者
=====
I/O模型
阻塞式IO: blocking IO
同步阻塞IO模型是最簡單的IO模型,用戶線程在內核進行IO操作時被阻塞,處理不可中斷睡眠,此過程中第一階段它要一直處于等待狀態.
非阻塞式IO:nonblocking IO
第一階段它要盲等待(輪循),這種情況下, 會影響系統的整體性能,大量用戶請求的情況下, 會降低性能.
復用型IO: multiplexing IO
也被稱之為多路IO復用.其有selet(),poll(),select()等函數,select()要求最多不能超過1024個調用,prefork就是基于select的多路利用模型, 其select幫調用者阻塞,調用者能接受其它請求,第二階段也會被阻塞(數據從內核空間至用戶進程空間的過程). 通常一個進程只能處理一個IO,但web場景一般都是兩路IO(磁盤和網絡). 在內核中有新的IO調用,當調用者發起IO調用時,內核中有一個代理人(select,poll)幫其阻塞,并將請求轉換為內核能理解的內容.
事件驅動式IO:signal driven IO
調用者發起調用后,被調用者收到請求后,立即返回收到消息(即在此動作中,調用者向內核注冊了一個函數),當內核處理完成后, 再通知調用者.第一階段非阻塞,第二階段是阻塞的.event模型也采用了此種IO機制. nginx也是采用了此種IO機制(并且還是邊緣觸發,其也支持異步IO機制). 當有IO調用已經在內核完成時, 進程正忙于處理其它請求,未能處理新到的IO事件,此時內核將完成的事件存放于內核某位置,進程空閑時通過回調函數再進行讀取.
異步IO
其由內核完成兩個階段后,再通知調用者,其epoll()函數就是異步IO機制.
mmap機制
直接將磁盤的地址映射到內存中,通知進程過來讀取.
=======
一次完整的READ操作:
- 第一階段: 等待數據準備好, 從磁盤到內存中.
- 第二階段: 數據從內核空間至進程空間(此階段被理解為真正的IO調用)