IO模型總結

咱們常說的IO模型主要是從Unix上拓展而來,因此提到IO模型通常都只是Unix下的IO模型,Unix下有5種可用的IO模型:linux

  • 阻塞式IO
  • 非阻塞式IO
  • IO複用
  • 信號驅動IO
  • 異步IO

除了【異步IO】之外,其餘所有是同步IO,下面咱們就每一個概念詳細說一下。編程

一、阻塞式IO數組

recvfrom 是系統調用,除非有數據返回或者發生錯誤纔會返回,最多見錯誤就是信號中斷,進程在調用recvfrom一直到它返回數據這段時間都是被阻塞的。安全

二、非阻塞IO模型網絡

進程把一個套接字設置成非阻塞是在通知內核:當全部請求IO操做必需要把本進程投入睡眠才能完成的時候,不要把本進程投入睡眠,而是返回一個錯誤。異步

當一個應用進程對一個非阻塞進程進行循環調用的recvfrom的時候,咱們稱之爲輪詢(polling),這樣的模型每每會消耗大量的cpu。socket

三、I/O複用模型函數

IO多路複用指的是單個線程經過追蹤管理每一個IO流的狀態來同時管理多個IO流。性能

select poll epoll是IO多路複用的多個具體實現,之因此有三個實現是有前後順序的。線程

select

  • select是最初實現的IO多路複用,select主要有如下問題
  • select會修改傳入的參數數組,這個對一個會調用不少次的函數很不友好。
  • select中若是一個socketIO出現了數據,那麼select會返回可是不會告訴你是那個socket上有數據,須要你本身去輪詢,若是數量大,開銷也會變大。
  • select只能監視1024個連接,這個跟linux系統參數有關係。
  • select不是線程安全的,例如一個socket被加入select,另一個線程又要關閉socket,那麼select是不支持的,會發生沒法預知的錯誤。

poll

poll修復了select大部分問題,例如再也不修改入參數組,去除了1024個連接的限制,可是poll仍然不是線程安全的,這會致使你仍是隻能在一個線程裏處理一組io,而不是多個線程來處理一組IO。

epoll

epoll是IO複用的最新實現,epoll修復了poll和select的絕大部分問題,而且提高了很是高的效率,例如:

  • epoll是線程安全的
  • epoll不只會返回數據,並且還會告訴你是哪一個socket有數據。

epoll缺點是隻支持linux,在BSD中對應實現的是kqueue

性能對比:

能夠看出epoll相對於select 和poll不會隨着連接的增多而出現性能上的大幅度降低。

 

四、信號驅動IO模型

這種模型是在套接字中設置一個信號驅動函數,當第一次請求數據的時候會馬上返回。當數據準備完畢的時候,內核會爲這個進程產生一個信號,就會調用一開始進程內的驅動函數,在函數中咱們能夠完成數據的複製處理,這種模式的優點在於在等待的期間進程不會被阻塞。

五、異步IO模型

這種模型的工做機制是告知內核我要啓動某個操做,而且讓內核在完成之後通知我,其中整個操做包含了數據從內核複製到用戶進程中。

異步IO模型和信號驅動IO模型的區別在於,信號IO模型只是收到內核通知說數據準備完畢,可是複製數據這個操做仍是由用戶進程來完成,可是異步IO模型從內核態複製數據到用戶態包含通知用戶進程都是在內核中進行完畢的。

 

 

咱們把幾種常見的IO模型進行對比:

根據上述定義,前四種模型,阻塞IO,非阻塞IO,信號驅動IO,多路複用IO都是同步IO,只有最後一種纔是真正的異步IO。

 

順便貼一下關於IO多路複用的形象化理解:http://www.zhihu.com/question/32163005

 

參考資料:unix網絡編程第六章部分章節

相關文章
相關標籤/搜索