i/o多路復用是為了解決程序或執行緒阻塞到某個i/o系統呼叫而出現的技術,使程序或執行緒不阻塞某個特定的i/o系統呼叫;
i/o多路復用機制包括select、poll、epoll;i/o復用可以監視多個描述符,一旦某個描述符就緒,能夠通知程式進行相應的操作;
它的標頭檔案和函式原型如下:
#includeint select(int nfds,fd_set * readfds,fd_set * writefds,fd_set * exceptfds,struct timeval *timeout)
select()函式監視的檔案描述符分3類,分別是writefds、readfds、exceptfds;呼叫select()函式會阻塞,直到有描述符就緒或者超時才返回,當函式返回後,可以通過遍歷fdset來找到就緒的檔案描述符
引數含義:
nfds:要監視的檔案描述符的範圍,linux上最大值一般為1024
readfds:監視的可讀描述符集合
writefds:監視的可寫 描述符集合
exceptfds:監視的錯誤異常描述符集合
timeout:超時時間,它告知核心等待所指定描述字中的任何乙個就緒可花多少時間;timeval結構用於指定這段時間的秒數和微秒數
select()和poll()系統呼叫的本質一樣,與select()在本質上沒有多少差別,管理多個描述符也是進行輪詢的,但是poll()沒有最大檔案描述符數量的限制;它和select()存在同乙個缺點,包含大量檔案描述符的陣列被整體複製與使用者態和核心態的位址空間,它的開銷隨檔案描述符數量的增加而線性增大
所需標頭檔案和函式原型如下:
#includeint poll(struct pollfd * fds,nfds_t nfds,int timeout);
引數含義:
fds:與select()使用的fd_set的方式不同,poll()使用乙個pollfd的指標實現;乙個pollfd結構體包括監視的檔案描述符和事件
struct pollfd
nfds:用來指定第乙個引數陣列元素個數
timeout:指定等待的毫秒數
相對於select()和poll(),epoll更加靈活,沒有描述符限制,epoll使用乙個檔案描述符管理多個描述符,將使用者關心的檔案描述符的事件存放在核心的乙個時間表中,這樣在使用者空間和核心空間只需要一次
//epoll操作的三個介面
#include//該函式生成乙個epoll專用的檔案描述符
int epoll_create(int size) //size用來告訴核心監聽的數目一共多大,從linux 2.6.8之後就被忽略
//epoll的事件註冊函式,註冊要監聽的事件型別
int epoll_ctl(int epfd,int op,int fd,struct epoll_event * event);
//epfd:epoll專用的檔案描述符,create的返回值
//op:表示動作;add註冊新的fd到epfd中; mod修改已註冊的監聽事件; del刪除乙個fd;
//struct epoll_event結構如下:
typedef union epoll_data
epoll_data_t //儲存觸發事件的某個檔案描述符的相關資料
//感興趣的事件和觸發事件
struct epoll_event
//等待事件的產生,收集epoll監控的事件中已經發生的事件
int epoll_wait(int epfd,struct epoll_event * events,int maxevents,int timeout);
//events不可以是空指標,核心只負責把資料複製到這個events陣列中,不會去幫助我們在使用者態中分配記憶體
//maxevents:核心中有多少個events
epoll對檔案描述符的操作有兩種模式:
lt(level trigger)模式:該模式是預設模式,支援block和no_block socket;當epoll_wait檢測到描述符事件發生並將該事件通知應用程式,應用程式不立即處理該事件,下次呼叫epoll_wait時,會再次響應應用程式並通知此事件,在高併發、大流量情況下,效率低於et模式;只要有資料沒有被獲取,核心就不斷通知,不用擔心事件丟失情況
et(edge trigger)模式:高效模式;只支援no_block socket,當epoll_wait檢測到描述符事件發生並將此事件通知應用程式,應用程式必須立刻處理,如果不處理,下次呼叫epoll_wait時,不會再次響應應用程式並通知此事件; 在高併發、大流量情況下,效率非常高,需要細緻的處理每個請求,否則容易丟失事件
select()、poll()、epoll()應用場景對比:
Linux IO多路復用
一.select 函式 include include include int select int n,fd set readfds,fd set writefds,fd set exceptfds,struct timeval timeout fd clr int fd,fd set set f...
Linux IO多路復用 多路轉接
io多路復用 多路轉接 在沒有io多路復用技術前,程序在同一時間只能監控乙個io狀態 乙個檔案描述符的狀態 例如a和b兩個檔案在操作,定的順序是a前b後,那麼在a阻塞過程中 b在後面也是不能被操作的,這樣會造成資源浪費 響應緩慢。io多路復用 同時監控多個io檔案描述符狀態,如果沒有準備好的描述符 ...
Linux I O多路復用(select)
i o多路復用是在多執行緒或多程序程式設計中常用技術。主要是通過select epoll poll三個函式支援的,就是通過記錄跟蹤每乙個sock i o流 的狀態來同時管理多個i o流,i o 多路復用技術通過把多個 i o 的阻塞復用到同乙個 select 的阻塞上,從而使得系統在單執行緒的情況下...