(PHP7內核剖析-2) I/O模型

1.同步:我客戶端(C端調用者)一個功能,該功能沒有結束前,我死等結果。
2.異步:我(c端調用者)調用一個功能,不知道該功能結果,該功能有結果後通知我,即回調通知
3.阻塞:就是調用我(s端被調用者,函數),我(s端被調用者,函數)沒有徹底接受完數據或者沒有獲得結果以前,我不會返回。
4.非阻塞:就是調用我(s端被調用者,函數),我(s端被調用者,函數)當即返回,得出結果後通知調用者

五種I/O模型程序員

(1) 阻塞I/O (Blocking I/O)網絡

blocking

當用戶進程進行系統調用時,內核就開始了I/O的第一個階段,準備數據到緩衝區中,當數據都準備完成後,則將數據從內核緩衝區中拷貝到用戶進程的內存中,這時用戶進程才解除block的狀態從新運行。數據結構

(2) 非阻塞I/O (Non-Blocking I/O)異步

non_blocking

用戶進程只有在第二個階段被阻塞了,而第一個階段沒有阻塞,可是在第一個階段中,用戶進程不須要盲等,不停的去輪詢內核,看數據是否準備好了,所以該模型是比較消耗CPU的。async

(3) I/O複用(I/O Multiplexing)函數

mutiplexing

I/O執行的兩個階段都是用戶進程都是阻塞的,可是兩個階段是獨立的,在一次完整的I/O操做中,該用戶進程是發起了兩次系統調用。和阻塞I/O不一樣的是第一段能夠等待多個描述符就緒spa

(4) 信號驅動的I/O (Signal Driven I/O)進程

singal

只有在I/O執行的第二階段阻塞了用戶進程,而在第一階段是沒有阻塞的。該模型在I/O執行的第一階段,當數據準備完成以後,會主動的通知用戶進程數據已經準備完成,即對用戶進程作一個回調。該通知分爲兩種,一爲水平觸發,即若是用戶進程不響應則會一直髮送通知,二爲邊緣觸發,即只通知一次。ip

(5) 異步I/O (Asynchrnous I/O)內存

asynchrnous

當用戶進程發起系統調用後,馬上就能夠開始去作其它的事情,而後直到I/O執行的兩個階段都完成以後,內核會給用戶進程發送通知,告訴用戶進程操做已經完成了。

I/O多路複用技術

select

(1).select()的機制中提供一fd_set的數據結構,每個元素都能與一打開的文件句柄(無論是Socket句柄,仍是其餘 文件或命名管道或設備句柄)創建聯繫,創建聯繫的工做由程序員完成, 當調用select()時,由內核根據IO狀態修改fd_set的內容,由此來通知執行了select()的進程哪一Socket或文件可讀或可寫。主要用於Socket通訊當中。

(2).程序執行select後,若是沒有數據輸入,程序會一直等待(阻塞時),直到有數據爲止,也就是程序中無需循環和sleep。

(3).每次調用select,都須要把fd_set集合從用戶態拷貝到內核態,這個開銷在fd_set不少時會很大

(4).同時每次調用select都須要在內核遍歷傳遞進來的全部fd_set,這個開銷在fd_set不少時也很大

(5).select支持的文件描述符數量過小了,默認是1024

poll

(1).poll的實現和select很是類似,只是描述fd_set集合的方式不一樣,poll使用pollfd鏈表結構而不是select的fd_set結構,其餘的都差很少。

(2).監視描述符個數無上限;

epoll/kqueue

(1).監視描述符個數無上限;(2).效率提高,不是輪詢的方式,不會隨着fd數目的增長效率降低。只有活躍可用的fd纔會調用callback函數;即epoll/kqueue最大的優勢就在於它只管你「活躍」的鏈接,而跟鏈接總數無關,所以在實際的網絡環境中,epoll/kqueue的效率就會遠遠高於select和poll。(3).內存拷貝,利用mmap()文件映射內存加速與內核空間的消息傳遞;