標籤:lex 讀取 訊號 分享 from nio 特點 bsp 資料
本章內容
1 同步,非同步,阻塞,非阻塞的概念
2 五種IO模型:阻塞式IO,非阻塞式IO,多工IO,訊號驅動IO,非同步IO 各自的特點
同步,非同步,阻塞,非阻塞(注意:這裡是從使用者線程和核心層面來介紹概念的)
同步和非同步(描述的是使用者線程與核心的互動方式 - 訊息的通訊機制)
1 同步 使用者線程發起IO後需要等待
2 非同步 使用者線程發起IO請求後仍然繼續執行,當核心操作完成後會通知使用者線程,或者調用使用者線程註冊的回呼函數
阻塞和非阻塞(描述的是程式等待調用結果是的狀態 - 調用者的狀態)
1 阻塞 在調用結果返回之前,調用者的執行線程會掛起,線程不能做其它事情,只有等待結果返回才能往下執行
2 非阻塞 IO操作被調用後立即返回調用者一個狀態值,無需等待IO操作徹底完成
IO模型
介紹
作業系統為了安全,將記憶體空間分成了使用者空間和核心空間,使用者進程無法直接操作底層硬體,只能將請求提交給CPU,由CPU去執行
進程(線程)將請求提交給CPU,等待CPU返回資料(這是一個兩段式的過程)
1 等待資料準備:核心從IO裝置將資料拷至記憶體空間的Buffer中
2 核心將資料從內部的Buffer中拷貝至進程空間
注意:核心在IO操作時,會為每一個IO裝置維護一個Buffer,等待資料輸入到Buffer,從Buffer複製到進程記憶體空間,都需要時間,根據等待模式可以分為:
1 blocking IO 阻塞式IO (兩段都阻塞)
2 nonblocking IO 非阻塞式IO (第一段不阻塞,第二段阻塞)
3 IO multiplexing IO複用 (兩段都阻塞)
4 signal driven IO 訊號驅動IO (第一段不阻塞,第二段阻塞)
5 asynchronus IO 非同步IO (兩段都不阻塞)
下面將對以上五種模型做一個詳細的介紹
阻塞式IO
1 使用者線程在讀寫時阻塞,系統調用不返回調用結果並讓當前線程一直阻塞,只有當該系統調用獲得結果或者逾時出錯時才返回
:
1 recvfrom 發起系統調用,當核心無資料報準備好時,要等待資料準備 (第一段) 應用進程阻塞
2 當核心資料準備好後,將資料拷貝至使用者空間(第二段)應用進程阻塞 拷貝完成後,返回成功,讓使用者進程去處理資料包,此時阻塞結束,將控制權移交給應用進程
2 缺點
使用者進程在IO過程中被阻塞,不能做任何事情,對CPU的資源使用率不高
非阻塞式IO
1 使用者線程不斷髮起IO請求,資料未到達前時系統返回一個狀態值,資料到達後才真正讀取資料(需要使用者線程不斷確定資料報是否已經準備好)
:
1 當使用者進程recvfrom發起一個系統調用,核心無資料包準備好時會返回一個EWOULDBLOCK狀態,當使用者進程不知道核心有沒有準備好資料,需要通過不斷輪詢的方式去確定資料報是否準備好(這個過程使用者進程是非阻塞的)
2 當核心準備好資料後,核心將資料拷貝至進程空間(使用者進程阻塞)
2 缺點
使用者進程每次請求IO都可以立即返回,但是為了拿到資料,需不斷地輪詢,無謂地消耗了大量CPU
IO多工(模式介紹不是很詳細,將在後續BIO,NIO中進行詳細介紹)
1 使用者先將需要進行IO操作的socket添加到select中,然後等待阻塞函數select返回,當資料到達後,socket被啟用,select返回,使用者線程就能接著發起read請求(注意:阻塞的是select)
這裡涉及到作業系統底層提供的 select,poll,epoll三種機制,這裡舉例為select(將在後續NIO中介紹此種模式的使用)
:
I/O多工是通過一種機制,可以監視多個描述符,一旦某個描述符就緒(一般是讀就緒或者寫就緒),能夠通知程式進行相應的讀寫操作
2 優點
可以在單個線程/進程中處理更多的串連
系統開銷小,系統不必建立進程/線程,也不必維護這些進程/線程,從而大大減小了系統的開銷
訊號驅動IO
:
1 先開啟通訊端的驅動式IO功能,並通過sigachtion系統調用安裝一個訊號處理函數,該系統調用立即返回,進程繼續工作,當資料報準備好時,核心為該進程產生一個SIGIO訊號 (第一段不阻塞)
2 接收到訊號後,再次發起系統調用,由核心將資料包拷貝至使用者空間(第二段阻塞)
非同步IO
1 工作機制 告知核心啟動某個操作,並讓核心在整個操作完成後通知我們
:
1 應用進程發起系統調用,核心立即返回一個狀態,此時進程繼續執行
2 當核心準備好資料,並將資料包拷貝至使用者空間後,通知進程處理 (兩段都不阻塞)
總結:
1 阻塞式IO:使用者進程發起系統調用,阻塞使用者進程,核心處理資料報,當兩段全部處理完成後,返回成功指示,再由使用者進程去處理資料報
2 非阻塞式IO:使用者進程發起系統調用,當核心資料報未準備好時,返回一個狀態給使用者進程,使用者進程繼續執行,未阻塞,但需要發起輪詢,不斷地詢問核心資料報是否準備好,當探索資料報已準備好時,阻塞使用者進程,由核心將資料報拷貝至使用者空間,拷貝完成後,返回成功指示,由使用者進程去處理
3 多工IO:使用者進程將IO請求註冊到select中,使用者進程繼續執行,select發起系統調用,核心做資料準備,當核心準備好資料時,返回相應使用者進程的可讀指示,使用者進程再發起系統調用,使用者進程阻塞,核心將資料報拷貝至使用者空間,拷貝完成後,返回成功指示,由使用者進程去處理
4 訊號驅動IO:使用者進程發起系統調用,當核心資料報未準備好時,返回一個狀態給使用者進程,使用者進程繼續執行,未阻塞,當核心準備好資料時,通過訊號通知使用者進程,使用者進程再發起系統調用,使用者進程阻塞,核心將資料報拷貝至使用者空間,拷貝完成後,返回成功指示,由使用者進程去處理
5 非同步IO:使用者進程發起系統調用,當核心資料包未準備好是,返回一個狀態給使用者進程,使用者進程繼續執行,未阻塞,當核心準備好資料,並將資料拷貝至使用者空間後,通知使用者進程去直接處理資料報
JAVA - IO模型