天天看點

IO複用(較詳細)

程序與線程的描述

一個程序至少會建立一個線程,多個線程共享一個程式程序的記憶體。程式的運作最終是靠線程來完成操作的。線程的數量跟CPU核數有關,一個核最多能發出兩個線程。線程的操作主要分為:一:給CPU進行程式指令的執行。二:IO的操作(讀取或輸出資料)或者請求網絡資料。

IO複用形成原因

如果一個I/O流進來,我們就開啟一個程序處理這個I/O流。那麼假設現在有一百萬個I/O流進來,那我們就需要開啟一百萬個程序一一對應處理這些I/O流(——這就是傳統意義下的多程序并發處理)。思考一下,一百萬個程序,你的CPU占有率會多高,這個實作方式及其的不合理。是以人們提出了I/O多路複用這個模型,一個線程,通過記錄I/O流的狀态來同時管理多個I/O,可以提高伺服器的吞吐能力

IO模型

阻塞IO模型

IO複用(較詳細)

 非阻塞IO模型

IO複用(較詳細)

 IO複用模型

IO複用(較詳細)

 信号驅動式IO模型

IO複用(較詳細)

 異步IO模型

IO複用(較詳細)

多路複用的實作有多種方式:select、poll、epoll

select

調用過程

a. 從使用者空間将fd_set拷貝到核心空間
b. 注冊回調函數
c. 調用其對應的poll方法
d. poll方法會傳回一個描述讀寫是否就緒的mask掩碼,根據這個mask掩碼給fd_set指派。
e. 如果周遊完所有的fd都沒有傳回一個可讀寫的mask掩碼,就會讓select的程序進入休眠模式,直到發現可讀寫的資源後,重新喚醒等待隊列上休眠的程序。如果在規定時間内都沒有喚醒休眠程序,那麼程序會被喚醒重新獲得CPU,再去周遊一次fd。
f. 将fd_set從核心空間拷貝到使用者空間      
優缺點
缺點:兩次拷貝耗時、輪詢所有fd耗時,支援的檔案描述符太小
優點:跨平台支援      

poll

調用過程(與select完全一緻)

優缺點

優點:連接配接數(也就是檔案描述符)沒有限制(連結清單存儲)
缺點:大量拷貝,水準觸發(當報告了fd沒有被處理,會重複報告,很耗性能)      

epoll

epoll的ET與LT模式

LT:延遲處理,當檢測到描述符事件通知應用程式,應用程式不立即處理該事件。那麼下次會再次通知應用程式此事件。

ET:立即處理,當檢測到描述符事件通知應用程式,應用程式會立即處理。

ET模式減少了epoll被重複觸發的次數,效率比LT高。我們在使用ET的時候,必須采用非阻塞套接口,避免某檔案句柄在阻塞讀或阻塞寫的時候将其他檔案描述符的任務餓死

調用過程

a. 當調用epoll_wait函數的時候,系統會建立一個epoll對象,每個對象有一個evenpoll類型的結構體與之對應,結構體成員結構如下。

rbn,代表将要通過epoll_ctl向epll對象中添加的事件。這些事情都是挂載在紅黑樹中。

rdlist,裡面存放的是将要發生的事件

b. 檔案的fd狀态發生改變,就會觸發fd上的回調函數

c. 回調函數将相應的fd加入到rdlist,導緻rdlist不空,程序被喚醒,epoll_wait繼續執行。

d. 有一個事件轉移函數——ep_events_transfer,它會将rdlist的資料拷貝到txlist上,并将rdlist的資料清空。

e. ep_send_events函數,它掃描txlist的每個資料,調用關聯fd對應的poll方法去取fd中較新的事件,将取得的事件和對應的fd發送到使用者空間。如果fd是LT模式的話,會被txlist的該資料重新放回rdlist,等待下一次繼續觸發調用。

優缺點
優點:      
  1. 沒有最大并發連接配接的限制
  2. 隻有活躍可用的fd才會調用callback函數
  3. 記憶體拷貝是利用mmap()檔案映射記憶體的方式加速與核心空間的消息傳遞,減少複制開銷。(核心與使用者空間共享一塊記憶體)

隻有存在大量的空閑連接配接和不活躍的連接配接的時候,使用epoll的效率才會比select/poll高

總結

IO分兩階段:

1.資料準備階段
2.核心空間複制回使用者程序緩沖區階段      

一般來講:阻塞IO模型、非阻塞IO模型、IO複用模型(select/poll/epoll)、信号驅動IO模型都屬于同步IO,因為階段2是阻塞的(盡管時間很短)。隻有異步IO模型是符合POSIX異步IO操作含義的,不管在階段1還是階段2都可以幹别的事。

IO複用(較詳細)