Linux系統IO分爲內核準備數據和將數據從內核拷貝到用戶空間兩個階段。html
這張圖大體描述了數據從外部磁盤向運行中程序的內存中移動的過程。linux
操做系統的核心是內核,獨立於普通的應用程序,能夠訪問受保護的內存空間,也有訪問底層硬件設備的全部權限。爲了保證用戶進程不能直接操做內核,保證內核的安全,操做系統將虛擬空間劃分爲兩個部分,一個部分爲內核空間,一部分爲用戶空間。ajax
網絡IO的本質就是socket的讀取,socket在linux系統被抽象爲流,IO能夠理解爲對流的操做。對於一次IO訪問(以read爲例),數據會先被拷貝到操做系統內核的緩衝區,而後纔會從操做系統內核的緩衝區拷貝到應用程序的地址空間中。因此說,當一個read操做發生時,它會經歷兩個階段:瀏覽器
第一個階段:等待數據準備緩存
第二個階段:將數據從內核拷貝到進程中安全
對於socket流而言:服務器
第一步:一般涉及等待網絡上的數據分組到達,而後複製到內核的某個緩衝區。網絡
第二步:把數據從內核緩衝區複製到應用進程緩衝區。異步
固然,若是內核空間的緩衝區中已經有數據了,那麼就能夠省略第一步。至於爲何不能直接讓磁盤控制器把數據送到應用程序的地址空間中呢?最簡單的一個緣由就是應用程序不能直接操做底層硬件。socket
網絡應用須要處理的無非就是兩大類問題,網絡IO,數據計算。相對於後者,網絡IO的延遲,給應用帶來的性能瓶頸大於後者。
——————————————————————————————
參考:http://www.cnblogs.com/dongguacai/p/5770287.html
同步:
所謂同步,就是在發出一個功能調用時,在沒有獲得結果以前,該調用就不返回。也就是必須一件一件事作,等前一件作完了才能作下一件事。
例如普通B/S模式(同步):提交請求->等待服務器處理->處理完畢返回
異步:
異步的概念和同步相對。當一個異步過程調用發出後,調用者不能馬上獲得結果。實際處理這個調用的部件在完成後,經過狀態、通知和回調來通知調用者。
例如 ajax請求(異步): 請求經過事件觸發->服務器處理(這時瀏覽器仍然能夠做其餘事情)->處理完畢
阻塞:
阻塞調用是指調用結果返回以前,當前線程會被掛起(線程進入非可執行狀態,在這個狀態下,cpu不會給線程分配時間片,即線程暫停運行)。函數只有在獲得結果以後纔會返回。
有人也許會把阻塞調用和同步調用等同起來,實際上他是不一樣的。對於同步調用來講,不少時候當前線程仍是激活的,只是從邏輯上當前函數沒有返回而已。 例如,咱們在socket中調用recv函數,若是緩衝區中沒有數據,這個函數就會一直等待,直到有數據才返回。而此時,當前線程還會繼續處理各類各樣的消息。
非阻塞:
非阻塞和阻塞的概念相對應,指在不能馬上獲得結果以前,該函數不會阻塞當前線程,而會馬上返回。
——————————————————————————————————
參考:http://blog.csdn.net/jay900323/article/details/18141217/
Linux的內核將全部外部設備都看做一個文件來操做,對一個文件的讀寫操做會調用內核提供的系統命令,返回一個file descriptor(fd,文件描述符)。而對一個socket的讀寫也會有相應的描述符,稱爲socketfd(socket描述符),描述符就是一個數字,它指向內核中的一個結構體(文件路徑,數據區等一些屬性)。
unix提供的5種IO模型:
以套接字接口爲例,在進程空間中調用recvfrom(用於從(已鏈接)套接口上接收數據,並捕獲數據發送源的地址),其系統調用直到數據包到達且被複制到應用進程的緩存區種或者發生錯誤時才返回,在此期間一直會等待,進程在從調用recvfrom開始到它返回的整段時間內都是被阻塞的,所以被稱爲阻塞IO模型。
recvfrom從應用層到內核的時候,若是緩衝區沒有數據的話,就直接返回一個錯誤,通常都對非阻塞IO模型進行輪詢檢查這個狀態,看內核是否是有數據到來。
linux系統提供select/poll,進程經過將一個或者多個fd傳遞給select/poll系統調用,阻塞在select操做上,這樣select/poll能夠幫助咱們偵測多個fd是否處於就緒狀態。select/poll順序掃描fd是否就緒,但支持的fd數量有限,所以使用受到一些制約。Linux提供的epoll系統調用,採用基於事件驅動方式代替順序掃描,所以性能更高,當有fd就緒時,當即回調函數rollback。
經過系統調用sigaction執行一個信號處理函數(此係統調用當即返回,進程繼續工做,非阻塞),當數據準備就緒時,就爲該進程生成一個SIGIO信號,經過信號回調通知應用程序調用recvfrom來讀取數據。
告知內核啓動某個操做,並讓內核在整個操做完成後(包括將數據從內核複製到用戶本身的緩存區)通知咱們。這種模型與信號驅動模型的主要區別是:信號驅動模型由內核通知咱們什麼時候能夠開始一個IO操做,異步模型由內核通知咱們IO操做什麼時候已經完成。
_________________________________________
參考:《Netty權威指南》