I/O模型

參考鏈接

I/O多路複用
IO多路複用之select、poll、epoll詳解
epoll講解
深入Go語言網絡庫的基礎實現
I/O模型

I/O模型

1.1 阻塞I/O模型

  • 最常用的I/O模型,默認情況下,所有文件操作都是阻塞的。
  • 比如I/O模型下的套接字接口:在進程空間中調用recvfrom,其系統調用直到數據包到達且被複制到應用進程的緩衝區中或者發生錯誤時才返回,在此期間一直等待。
  • 進程在調用recvfrom開始到它返回的整段時間內都是被阻塞的,所以叫阻塞I/O模型。
    在這裏插入圖片描述

1.2 非阻塞I/O模型
recvfrom從應用層到內核的時候,就直接返回一個EWOULDBLOCK錯誤,一般都對非阻塞I/O模型進行輪詢檢查這個狀態,看內核是不是有數據到來
在這裏插入圖片描述

1.3 I/O複用模型

  • Linux提供select/poll,進程通過將一個或多個fd傳遞給select或poll系統調用,阻塞在select操作上,這樣,select/poll可以幫我們偵測多個fd是否處於就緒狀態。
  • select/poll是順序掃描fd是否就緒,而且支持的fd數量有限,因此它的使用受到了一些制約。
  • Linux還提供一個epoll系統調用,epoll使用基於事件驅動方式代替順序掃描,因此性能更高。當有fd就緒時,立即回調函數rollback。
    在這裏插入圖片描述

1.4 信號驅動I/O模型
首先開啓套接口信號驅動I/O功能,並通過系統調用sigaction執行一個信號處理函數(此係統調用立即返回,進程繼續工作,非阻塞)。當數據準備就緒時,就爲改進程生成一個SIGIO信號,通過信號回調通知應用程序調用recvfrom來讀取數據,並通知主循環函數處理數據。
在這裏插入圖片描述

1.5 異步I/O

  • 告知內核啓動某個操作,並讓內核在整個操作完成後(包括數據的複製)通知進程。
  • 信號驅動I/O模型通知的是何時可以開始一個I/O操作,異步I/O模型有內核通知I/O操作何時已經完成。
    在這裏插入圖片描述

I/O模型區別

我相信很多人看過網上一篇關於epoll的講解,在這裏我用裏面的舉例來說。假如現在我要等快遞員給我派送快遞,那麼各種I/O模型對應實際就是:

  • 阻塞I/O:我在家裏一直等快遞員電話,電話沒來的時候我就睡覺,電話來了我就醒過來拿快遞
  • 非阻塞I/O:我就一直醒着,而且我一直打電話給快遞員:我的快遞來了沒?。就這樣一直循環着
  • I/O多路複用:我用手機下載了一個快遞助手,然後就去睡覺了。當有快遞來的時候,快遞助手就會響鈴叫醒我,然後我再看是哪個快遞就行了。

信號驅動和異步驅動的區別

鏈接

  • 信號驅動IO是指:進程預先告知內核,使得 當某個socketfd有events(事件)發生時,內核使用信號通知相關進程。
  • 異步IO(Asynchronous IO)是指:進程執行IO系統調用(read / write)告知內核啓動某個IO操作,內核啓動IO操作後立即返回到進程。IO操作即內核當中的服務例程。

異步I/O和信號驅動I/O的區別很容易被混淆。前者與後者的區別在於啓用異步I/O意味着通知內核啓動某個I/O操作,並讓內核在整個操作(包括數據從內核複製到用戶緩衝區)完成時通知我們。也就是說,異步I/O是由內核通知我們I/O操作何時完成,即實際的I/O操作也是異步的;而 信號驅動I/O是由內核通知我們何時可以啓動一個I/O。
I/O究竟什麼時候能用這個信息實際上只有內核才能 事先知道,因爲是內核在最終處理系統中的所有打開的描述符。

  • 信號驅動I/O模型
    • 內核:I/O能用了。
    • 進程:接受到I/O能用的消息並執行接下來的操作。
  • 異步I/O模型
    • 內核:等待這個I/O有消息了,接受到數據。
    • 進程:從緩存中得到數據。

信號驅動的作用在於在等待I/O可用的過程中可以執行其它的指令,這種方法從理論上看 倒是不錯。由於進程已經休眠,就不會再佔用CPU,僅當I/O可用時它才恢復執行。但是這種方法的問題在於信號處理的開銷有點大。若只是少數的請求還沒有問題,若是每分鐘收到100個請求,那就幾乎一直都在捕獲信號。每秒鐘捕獲上百個信號的開銷是相當大的,不單是進程,對於內核發送信號的開銷而言也是一樣的。
  因此,在高性能的服務器編程中,用異步I/O來處理多個I/O更爲高效。當然,也可以用I/O複用模型來實現(epoll是一個相當高效的方法),但是對於Regular File來說,是不能使用epoll的,因爲不能設置非阻塞模式(O_NOBLOCK 方式對於傳統文件句柄是無效的),這個時候,異步I/O是一個很不錯的選擇

I/O多路複用

  1. I/O多路複用就是通過一種機制,一個進程可以監視多個描述符,一旦某個描述符就緒(一般是讀就緒或者寫就緒),能夠通知程序進行相應的讀寫操作。
  2. 與多進程和多線程技術相比,I/O多路複用技術的最大優勢是系統開銷小,系統不必創建進程/線程,也不必維護這些進程/線程,從而大大減小了系統的開銷。

使用場景

IO多路複用是指內核一旦發現進程指定的一個或者多個IO條件準備讀取,它就通知該進程。IO多路複用適用如下場合:
  1)當客戶處理多個描述符時(一般是交互式輸入和網絡套接口),必須使用I/O複用。
  2)當一個客戶同時處理多個套接口時,這種情況是可能的,但很少出現。
  3)如果一個TCP服務器既要處理監聽套接口,又要處理已連接套接口,一般也要用到I/O複用。
  4)如果一個服務器即要處理TCP,又要處理UDP,一般要使用I/O複用。
  5)如果一個服務器要處理多個服務或多個協議,一般要使用I/O複用。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章