1 阻塞IO模型html
從字面來理解,就是調用時可能被阻塞, 什麼叫阻塞,要知道一個進程有N種狀態,學過OS都知道 若是阻塞,就會把當前進程放在某個條件的阻塞隊列裏。 直到條件知足了,纔會轉移此進程進入就緒隊列。 固然,就緒隊列還有個優先級的概念,就不扯遠了。 阻塞IO. 1)調用API,好比 recvfrom,從用戶態進入內核態。 2) 內核發現無數據,將進程信息節點插入阻塞隊列,等待數據。 3)進程一直阻塞,阻塞,阻塞。 4)數據到達,內核拷貝數據, 數據的流動路徑是:網卡---socket內核緩衝區---用戶的緩衝區。 5)拷貝完成後返回,咱們就能夠獲得recvfrom的結果,成功/失敗。
2 非阻塞IO模型java
什麼叫非阻塞,就是從用戶角度來講,函數當即能夠獲得結果:成功/失敗。 1)用戶調用recvfrom,內核發現無數據,當即返回結果。 2)用戶調用recvfrom,內核發現無數據,當即返回結果。 3)用戶調用recvfrom,內核發現無數據,當即返回結果。 4)用戶調用recvfrom,內核發現有數據,將數據從socket內核緩衝區複製到 用戶緩衝區,返回結果。
3 IO複用模型redis
1)將多個須要監聽的fd給epoll,讓其監控。 注意:epoll自己是阻塞的,能夠設定時間。 2)epoll返回結果,用戶能夠知道哪些fd可讀,可寫,有異常等。 3)剩下的就是用戶本身按需操做fd. 好比redis就是使用IO複用模型。
備註:epoll的最大fd個數:cat /proc/sys/fs/file-max,跟內存關係比較大
4)信號驅動模型網絡
1)開啓socket信號驅動IO功能, 經過sigaction設置信號處理函數。 2)當socket有數據時,發生一個SIGIO信號, 執行以前的信號處理函數。 3)用戶邏輯放在信號處理函數裏實現。
5)異步IO異步
1)告知內核啓動某個操做,在內核完成全部的操做(包括複製數據到用戶緩衝區)後
經過信號機制通知用戶。 2)信號處理程序直接處理用戶緩衝區裏的數據,由於數據已經被內核複製完畢。 與信號驅動的區別是: 信號驅動經過信號告知,能夠啓動某個操做了。 異步IO通知用戶:我連複製數據的步驟都替你完成了,用戶只須要處理便可。
總結一下:socket
爲何會出現這麼多的模型?函數
需求來源於需求,咱們想一想在開發網絡程序時,對一個socket須要關注哪些方面?spa
1)這個socket可讀,可寫,有異常?code
2)有數據可操控時,複製數據到用戶緩衝區。htm
下面是我對這幾種IO模型的理解
是否解決socket 可用的問題 |
是否自動將數據從套接字緩衝區 複製到用戶緩衝區 |
評分 |
|
阻塞模型 |
× |
× |
★ |
非阻塞模型 |
× |
× |
★★ |
IO複用模型 |
√ |
× |
★★★ |
信號驅動 |
√ |
× |
★★★ |
異步IO |
√ |
√ |
★★★★★ |