i/o多路復用使得程式能夠同時監聽多個檔案描述符,這對提高程式的效能至關重要。linux下實現i/o復用的系統呼叫主要有select、poll和epoll。
select系統呼叫
select系統呼叫的用途是:在一段指定的時間內,監聽使用者感興趣的檔案描述符上的可讀、可寫和異常事件。
#include
intselect
(int nfds, fd_set* readfds, fd_set* writefds, fd_set* exceptfds,
struct timeval* timeout)
;nfds引數指定被監聽的檔案描述符的綜述,
它通常被設定為select監聽的所有檔案描述符中的最大值加1,
因為檔案描述符從0開始計數。
readfds、writefds和exceptfds分別指向可讀、可寫和異常
等事件對應的檔案描述符的集合。
該呼叫返回時候,核心將修改它們來通知執行緒哪些檔案描述符已經就緒。
fd_set結構體僅包含乙個整型陣列,該陣列的每個元素的每一位(bit)標記
乙個問價描述符。位操作過於繁瑣,我們此案用如下的巨集定義來訪問fd_set結構體中的位。
#include
fd_zero
(fd_set* fdset)
;//清除fdset中的所有位
fd_set
(int fd, fd_set* fdset)
;//設定fdset的位fd
fd_clr
(int fd, fd_set* fdset)
;//清除fdset的位fd
intfd_isset
(int fd, fd_set* fdset)
;//測試fdset的位fd是否被設定
timeout引數用來設定select函式的超時時間,如果該指標的成員為0則select立刻
返回,如果傳遞null給timeout,ze select將一直阻塞,直到某個檔案描述符就緒。
timeval結構體如下:
struct timeval
;select成功時返回就緒(可讀、可寫和異常)檔案描述符的總數。
如果超時沒有檔案描述符就緒,則返回0
;失敗時返回-
1並設定errno。
注:通過函式執行之後的三個fd_set*指標裡面的內容來判斷某乙個描述符
時候有事件發生(可讀、可寫或異常)。遍歷fd_set的時間複雜度為o
(n);
poll系統呼叫poll系統呼叫和select類似,也是在指定時間內輪詢一定數量的檔案描述符,以測試其中是否有就緒者。poll的原型如下:
#include
intpoll
(struct polled* fds, nfds_t nfds,
int timeout)
;fds引數是乙個polled結構型別的陣列,pollfd結構體中指定了我們感興趣的檔案描述符上發生的可讀、可寫和異常等事件。
struct pollfd
;nfds引數指定被監聽時間集合fds的大小。
timeout引數指定poll的超時值,單位是毫秒。當timeout為-
1時候,
poll將一直阻塞直到某個事件發生,當timeout為0時候,poll將立即返回。
其返回值的含義與select系統呼叫相同。
epoll系統呼叫epoll是linux特有的i/o復用函式,它在實現上與select、poll有很大差別。
最後總結一下三種io復用的區別:
截圖**於:linux高效能伺服器程式設計
I O多路復用之poll
poll的優點 1 poll 不要求開發者計算最大檔案描述符加一的大小。2 poll 在應付大數目的檔案描述符的時候速度更快,相比於select。3 它沒有最大連線數的限制,原因是它是基於鍊錶來儲存的。poll的缺點 1 大量的fd的陣列被整體複製於使用者態和核心位址空間之間,而不管這樣的複製是不是...
I O多路復用之select
阻塞i o模型 應用程式呼叫乙個i o函式,應用程式會一直等待資料準備好。如果資料沒有準備好,就會一直等待。只有當資料準備好,從核心拷貝到使用者空間io函式才成功返回。非阻塞i o模型 把乙個套介面設定成非阻塞告訴核心,當所有的i o操作無法完成時,不要將程序睡眠,而返回乙個錯誤資訊。此時i o操作...
IO多路復用之select
1 背景知識 我們首先來看看伺服器程式設計的模型,客戶端發來的請求服務端會產生乙個程序來對其進行服務,每當來乙個客戶請求就產生乙個程序來服務,然而程序不可能無限制的產生,因此為了解決大量客戶端訪問的問題,引入了io復用技術。即 乙個程序可以同時對多個客戶請求進行服務。也就是說io復用的 介質 是程序...