中斷包括程序中斷、時間中斷、I/O中斷和硬件失效中斷。當程序向內核發出I/O請求,內核執行I/O程序,I/O設備經過中斷的方式通知內核:」已發現須要的數據「,內核執行中斷程序迴應硬件設備:」已獲悉「。網絡
中斷機制在每一個OS中均可能有不同的實現,下面簡述Linux系統中的通常中斷機制,具體實現仍取決於開發者。異步
上半部分:內核經過中斷處理程序及時迴應發出中斷請求的硬件(儘快返回被中斷的工做中)。當I/O事件完成,I/O設備發送中斷信號到中斷控制器芯片,若是此時處理器容許中斷,中斷控制器向處理器發送一箇中斷請求的電信號,處理器在指令週期中的檢測中斷階段檢測到I/O中斷請求,馬上中止當前處理的程序並屏蔽中斷,跳到預先由內核設置好的內存地址讀取指令並執行,這個地址就是中斷處理函數的入口,內核在這個函數內計算出中斷號,根據中斷號運行對應的處理程序(該中斷處理程序來自於外部設備的驅動),完成中斷處理程序後即對硬件的中斷請求做出了迴應。在這個階段有時還會作另一些一樣對時間很敏感的工做,例如從硬件拷貝數據到系統內存緩衝區,如當網卡接收到的數據,以後能夠返回到被中斷的程序中繼續執行指令。函數
下半部分:完成對時間不是很是敏感的工做,這部分工做能夠日後推遲。例如處理系統內存中從硬件接收到的數據,若是此時完成了一個I/O請求的條件,能夠將阻塞在此I/O請求上的進程設置爲就緒態。‘spa
用戶空間的程序沒法直接執行內核代碼,由於內核的函數存放在受保護的系統空間內。應用程序經過軟中斷的方式,通知系統本身須要執行一個系統調用:經過引起一個異常促使系統從用戶態切換到系統態,執行一個異常處理函數,這個函數就是系統調用處理程序。操作系統
阻塞態是進程的一種執行態,此時進程不能被內核調度繼續執行。阻塞的緣由有不少種,能夠概括爲等待的事件仍未發生。在這裏咱們討論的阻塞與非阻塞就是進程在執行I/O調用以後的狀態。線程
當進程執行一個系統調用以請求I/O資源,但內核檢測到I/O資源被佔用或者數據未準備好,因此不能馬上響應線程爲其服務,進程的狀態被內核調整爲阻塞態,直到該I/O資源準備好並返回系統調用的結果,內核將進程執行態設置爲就緒態。相反,若是進程執行一個系統調用,該系統調用不管I/O資源準備好與否都當即返回某個結果,進程就不須要進入阻塞態且能夠繼續執行後續指令。兩種系統調用的區別在於:當操做系統沒有準備好程序申請的I/O資源時,進程是否會被內核設置爲阻塞態。設計
同步與異步是對請求方與被請求方之間的通訊方式。對象
同步(synchronous ):當請求方發送請求後,只能作獲取被請求方的響應的事情,能夠是什麼都不作,等待被請求方迴應結果(阻塞),也能夠是不斷地詢問被請求方是否有結果(非阻塞、輪詢-polling),但就是不會作與此次請求無關的其餘任務。當進程執行I/O請求後,被阻塞等待內核通知I/O事件完成,或者非阻塞地經過輪詢的方式詢問內核I/O事件是否完成,而不會去執行其餘不相干的代碼。blog
異步(Asynchronous):當請求方發送請求後,不關心結果,直接執行其餘任務的操做(非阻塞),等到被請求方處理完請求後再通知請求方,請求方在合適的時候再處理這個結果,或者在請求的時候就告訴被請求方當處理完請求後幫其乾點什麼。當程序執行I/O系統調用,該系統調用是非阻塞的,即會當即返回一個結果,程序能夠繼續執行後面的指令,這些指令不會涉及到這個結果,當內核通知其I/O事件完成後纔會考慮處理結果。或者設置回調函數,當I/O事件完成時執行回調函數。接口
BIO模型是同步阻塞的。
阻塞:進程執行系統調用請求獲取數據,被阻塞直到數據複製到系統緩衝區,並從系統緩衝區複製到應用緩衝區。
同步:因爲在內核準備數據這段時間,程序沒有作其餘工做,直到獲取到內核的結果。
NIO模型是同步非阻塞的。
非阻塞於:進程執行系統調用請求數據,當系統調用檢測系統緩衝區沒有準備好數據時,並無讓程序等待直到數據準備好,而是直接返回一個負數表明數據沒有準備好,程序能夠繼續執行後面的指令。
同步於:雖然程序能夠繼續執行後面的指令,可是想先收到數據再作其餘工做,經過輪詢的方式不斷詢問內核數據是否準備好。
在多路複用模型中,複用的是線程,即用一個線程監聽多個I/O流上可讀可寫的事件。
在以前的BIO模型與NIO模型中,服務端在一個線程裏只等待一個客戶端Socket文件I/O流上可讀或可寫的事件發生,這意味着一個線程只服務一個客戶端,當客戶端Socket文件的輸入流不可讀,線程同步地等待直到該輸入流可讀,而後讀取數據並處理。若是服務端進程要同時處理多個客戶端即監聽多個Socket文件上的I/O流可讀寫事件,須要增長線程數目。值得注意的是,除了根據客戶端數目1:1地增長線程數目來服務多個客戶端,也能夠經過設置線程池的方式,用若干個線程服務多個客戶端。但本質上,這兩種I/O模型中每一個線程都只能同時監聽一個Socket文件上的I/O流事件。
在I/O多路複用模型中,服務端在一個線程裏能夠同時監聽多個客戶端Socket文件上的I/O流。線程等待多個I/O流上的可讀可寫事件,當一個或以上的I/O流可讀/可寫事件發生,內核返回被包裝好的I/O流對象,線程串行地根據事件的類型對這些I/O流進行讀或者寫。
I/O多路複用是同步阻塞的。
阻塞於:當沒有一個I/O上有可讀或可寫事件發生,線程是被阻塞的,select()函數不能立刻返回(select函數選擇一個或以上的可讀寫I/O流)。值得注意的是,有的文章會根據:即便有部分I/O流不知足讀/寫條件也不會阻塞整個線程妨礙其餘I/O流讀寫這一觀點,認爲I/O複用是非阻塞的,這是對的,只是你們角度不一樣。
同步於:由於在發送I/O請求(select函數)後若是沒有可讀或可寫事件發生,線程是阻塞的,線程沒辦法執行其餘工做,因此是同步的。
異步I/O模型是異步非阻塞的。在該模型中,線程爲I/O請求執行的系統調用不會阻塞線程而是立刻返回,這次請求僅僅是通知內核將需求數據複製到應用緩衝區,以後線程能夠執行後面的指令,與NIO不一樣的是,AIO不會以輪詢地方式等待I/O操做完成,而是去執行其餘工做,直到內核將數據複製到應用緩衝區再通知線程,所以AIO是非阻塞的,異步的。