java io理解

自從接觸網絡編程,對java的IO已經感受雲裏霧裏,老感受有層窗戶紙擋着就是看不清楚。尤爲是同步(Synchronous)、異步(ASynchronous)、阻塞(blocking)和非阻塞(non-blocking)這些概念。這些概念的的由來與操做系統的發展是分不開的。爲何這麼說呢?這要從操做系統的內核態和用戶態提及:java

內核態: CPU能夠訪問內存全部數據, 包括外圍設備, 例如硬盤, 網卡. CPU也能夠將本身從一個程序切換到另外一個程序。(進城調度、文件讀取、TCP/IP協議棧等都是工做在內核態)linux

用戶態: 只能受限的訪問內存, 且不容許訪問外圍設備. 佔用CPU的能力被剝奪, CPU資源能夠被其餘程序獲取(程序員開發的程序就是工做再這一層)程序員

 

爲何要有用戶態和內核態

因爲須要限制不一樣的程序之間的訪問能力, 防止他們獲取別的程序的內存數據, 或者獲取外圍設備的數據, 併發送到網絡, CPU劃分出兩個權限等級 -- 用戶態 和 內核態編程

用戶態與內核態的切換網絡

全部用戶程序都是運行在用戶態的, 可是有時候程序確實須要作一些內核態的事情, 例如從硬盤讀取數據, 或者從鍵盤獲取輸入等. 而惟一能夠作這些事情的就是操做系統, 因此此時程序就須要先操做系統請求以程序的名義來執行這些操做.併發

這時須要一個這樣的機制: 用戶態程序切換到內核態, 可是不能控制在內核態中執行的指令,這種機制叫系統調用, 在CPU中的實現稱之爲陷阱指令(Trap Instruction)。異步

系統調用工做流程如:socket

一、用戶態程序執行系統調用.函數

二、CPU切換到內核態, 並跳到位於內存指定位置的指令, 這些指令是操做系統的一部分, 他們具備內存保護, 不可被用戶態程序訪問spa

三、這些指令稱之爲陷阱(trap)或者系統調用處理器(system call handler). 他們會讀取程序放入內存的數據參數, 並執行程序請求的服務

四、系統調用完成後, 操做系統會重置CPU爲用戶態並返回系統調用的結果

                                  

舉例來講:你要轉給張三1萬元,確定不能直接跑到銀行裏面,在銀行內網的電腦上噼裏啪啦轉給張三的帳戶一萬,你能夠試試,估計會悲劇了。。。

你能作的就是先排個號,而後乖乖的在櫃檯上填單子寫明張三的帳戶和轉款的金額,填完了交給櫃檯的服務人員,讓服務人員幫你你轉帳。在這個過程當中銀行就是內核,拍號就是系統調用,填寫的單子就是系統調用的參數,櫃檯服務人員就是內核線程,全部的工做都是內核線程完成的。

同理網絡編程也須要內核協助才能完成,如圖:

一、經過socket對象的read的方法發起系統調用

二、操做系統切換到內核態,同時將用戶線程掛起。

三、若是內核空間中有數據,就直接返回。若是沒有數據就阻塞等待網卡緩衝區滿了,將數據發送到內存。

四、將內核空間中的數據複製到用戶空間中。

 

同步與異步的主要區別就在於:當第一步調用完成以後用戶線程是否等待內核線程完成數據準備工做。

linux下有五種常見的IO模型。如圖:

Linux下5種IO模型的小結 

阻塞IO模型

阻塞IO模型是最多見的IO模型了,對於全部的「慢速設備」(socket、pipe、fifo、terminal)的IO默認的方式都是阻塞的方式。阻塞就是用戶進程放棄cpu,讓給其餘線程使用cpu。當前進程等待數據到來以後才繼續執行。(在linux中線程是輕量級進城)

 

   

非阻塞IO模型

非阻塞IO就是設置IO相關的系統調用爲non-blocaking,隨後進行的IO操做不管有沒有可用數據都會當即返回,並設置errno爲EWOULDBLOCK或者EAGAIN。咱們能夠經過主動check的方式(polling,輪詢)確保IO有效時,隨之進行相關的IO操做。固然這種方式看起來就彷佛不太靠譜,須要用戶進程不斷的去詢問浪費了太多的CPU時間,用寶貴的CPU時間作輪詢太不靠譜兒了。圖示:

 

多路複用IO模型

多路複用是讓阻塞發生在咱們的多路複用IO操做的系統調用上面,而不是咱們真正去執行IO的系統調用。使用這個方式的好處就是能夠同時監控多個用於IO的文件描述符。經過用戶進程來詢問太浪費cpu了,因而就將詢問的活交給內核來幹,內核能夠經過一個進程監控多個調用,省時又省力。

   

信號驅動IO模型

所謂信號驅動,就是利用信號機制,安裝信號SIGIO的處理函數(進行IO相關操做),經過監控文件描述符,當其就緒時,通知目標進程進行IO操做(signal handler)。這種方式更近了一步,當你須要數據的時候,只是發送一個信號量就行,當內核的數據就緒以後,就會通知用戶進程去複製數據。

     

異步IO模型

異步就是當你只須要發起一個一步的系統調用,操做系統內核不但把數據從網卡的緩衝區複製到內核空間,還講內核空間的數據複製到用戶空間。用戶進程須要作的就是使用數據。

 

   下圖是關於異步IO模型的圖示:

 

總結:io的變化就是抽象用戶進程任務的過程,使用戶進程從底層的的數據獲取操做中解脫出來。但並非有了新的io模型就不須要老的了,不一樣的io模型會有不一樣的使用場景!

相關文章
相關標籤/搜索