多路IO復用模型 select epoll 等

2021-06-05 09:25:57 字數 1784 閱讀 2250

同步阻塞io在等待資料就緒上花去太多時間,而傳統的同步非阻塞io雖然不會阻塞程序,但是結合輪詢來判斷資料是否就緒仍然會耗費大量的cpu時間。

多路io復用提供了對大量檔案描述符進行就緒檢查的高效能方案。

select

select誕生於4.2bsd,在幾乎所有平台上都支援,其良好的跨平台支援是它的主要的也是為數不多的優點之一。

select的缺點(1)單個程序能夠監視的檔案描述符的數量存在最大限制(2)select需要複製大量的控制代碼資料結構,產生巨大的開銷 (3)select返回的是含有整個控制代碼的列表,應用程式需要遍歷整個列表才能發現哪些控制代碼發生了事件(4)select的觸發方式是水平觸發,應用程式如果沒有完成對乙個已經就緒的檔案描述符進行io操作,那麼之後每次select呼叫還是會將這些檔案描述符通知程序。相對應方式的是邊緣觸發。

poll

poll 誕生於unix system v release 3,那時at&t已經停止了unix的源**授權,所以顯然也不會直接使用bsd的select,所以at&t自己實現了乙個和select沒有多大差別的poll。

poll和select是名字不同的孿生兄弟,除了沒有監視檔案數量的限制,select後面3條缺點同樣適用於poll。

面對select和poll的缺陷,不同的os做出了不同的解決方案,可謂百花齊放。不過他們至少完成了下面兩點超越,一是核心長期維護乙個事件關注列表,我們只需要修改這個列表,而不需要將控制代碼資料結構複製到核心中;二是直接返回事件列表,而不是所有控制代碼列表。

/dev/poll

sun在solaris中提出了新的實現方案,它使用了虛擬的/dev/poll裝置,開發者可以將要監視的檔案描述符加入這個裝置,然後通過ioctl()來等待事件通知。

/dev/epoll

名為/dev/epoll的裝置以補丁的方式出現在linux2.4中,它提供了類似/dev/poll的功能,並且在一定程度上使用mmap提高了效能。

kqueue

freebsd實現了kqueue,可以支援水平觸發和邊緣觸發,效能和下面要提到的epoll非常接近。

epoll

epoll誕生於linux 2.6核心,被公認為是linux2.6下效能最好的多路io復用方法。

int epoll_create(int size) 

int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event) 

int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout)

epoll支援水平觸發和邊緣觸發,理論上來說邊緣觸發效能更高,但是使用更加複雜,因為任何意外的丟失事件都會造成請求處理錯誤。nginx就使用了epoll的邊緣觸發模型。

這裡提一下水平觸發和邊緣觸發就緒通知的區別,這兩個詞**於計算機硬體設計。它們的區別是只要控制代碼滿足某種狀態,水平觸發就會發出通知;而只有當控制代碼狀態改變時,邊緣觸發才會發出通知。例如乙個socket經過長時間等待後接收到一段100k的資料,兩種觸發方式都會向程式發出就緒通知。假設程式從這個socket中讀取了50k資料,並再次呼叫監聽函式,水平觸發依然會發出就緒通知,而邊緣觸發會因為socket「有資料可讀」這個狀態沒有發生變化而不發出通知且陷入長時間的等待。

因此在使用邊緣觸發的 api 時,要注意每次都要讀到 socket返回 ewouldblock為止

IO模型 IO多路復用

用socket 一定會用到accept recv recvfrom這些方法 正常情況下 accept recv recvfrom都是阻塞的 如果setblocking false 整個程式就變成乙個非阻塞的程式了非阻塞的特點 沒有併發程式設計的機制 是乙個同步的程式 程式不會在某乙個連線的recv或...

多路IO復用模型 select epoll

我們先來介紹下nginx nginx 支援高併發連線 官方測試的是 併發連線但在實際生產中可製成2 4w併發連線數,得益於nginx使用最新的epoll linux 2.6核心 和kqueue freebsd 網路i o模型.而apache使用的則是傳統的select模型,其比較穩定的prefork...

IO模型 多路復用

乙個輸入操作通常包括兩個階段 應用程序被阻塞,直到資料從核心緩衝區複製到應用程序緩衝區中才返回。應該注意到,在阻塞的過程中,其它應用程序還可以執行,因此阻塞不意味著整個作業系統都被阻塞。因為其它應用程序還可以執行,所以不消耗 cpu 時間,這種模型的 cpu 利用率會比較高。應用程序執行系統呼叫之後...