這部分的東西在網絡編程經常能看到,不過在所有IO處理中都是類似的。
IO請求的兩個階段:
等待資源階段:IO請求一般需要請求特殊的資源(如磁盤、RAM、文件),當資源被上一個使用者使用沒有被釋放時,IO請求就會被阻塞,直到能夠使用這個資源。
使用資源階段:真正進行數據接收和發生。
舉例說就是排隊和服務。
在等待數據階段,IO分爲阻塞IO和非阻塞IO。
阻塞IO:資源不可用時,IO請求一直阻塞,直到反饋結果(有數據或超時)。
非阻塞IO:資源不可用時,IO請求離開返回,返回數據標識資源不可用
在使用資源階段,IO分爲同步IO和異步IO。
同步IO:應用阻塞在發送或接收數據的狀態,直到數據成功傳輸或返回失敗。
異步IO:應用發送或接收數據後立刻返回,數據寫入OS緩存,由OS完成數據發送或接收,並返回成功或失敗的信息給應用。
按照Unix的5個IO模型劃分
- 阻塞IO
- 非阻塞IO
- IO複用
- 信號驅動的IO
- 異步IO
從性能上看,異步IO的性能無疑是最好的。
各種IO的特點
- 阻塞IO:使用簡單,但隨之而來的問題就是會形成阻塞,需要獨立線程配合,而這些線程在大多數時候都是沒有進行運算的。Java的BIO使用這種方式,問題帶來的問題很明顯,一個Socket需要一個獨立的線程,因此,會造成線程膨脹。
- 非阻塞IO:採用輪詢方式,不會形成線程的阻塞。Java的NIO使用這種方式,對比BIO的優勢很明顯,可以使用一個線程進行所有Socket的監聽(select)。大大減少了線程數。
- 同步IO:同步IO保證一個IO操作結束之後纔會返回,因此同步IO效率會低一些,但是對應用來說,編程方式會簡單。Java的BIO和NIO都是使用這種方式進行數據處理。
- 異步IO:由於異步IO請求只是寫入了緩存,從緩存到硬盤是否成功不可知,因此異步IO相當於把一個IO拆成了兩部分,一是發起請求,二是獲取處理結果。因此,對應用來說增加了複雜性。但是異步IO的性能是所有很好的,而且異步的思想貫穿了IT系統放放面面。