i/o復用(本身是阻塞的)
網路程式需要使用i/o復用技術的情況:
1.客戶端程式需要同時處理多個socket。
2.客戶端需要同時處理使用者輸入和網路連線
3.tcp伺服器要同時處理監聽socket和連線socket
4.伺服器要同時處理tcp請求和udp請求
5.伺服器要同時監聽多個埠,或者處理多種服務。
linux下實現i/o復用的系統呼叫主要有select,poll和epoll
select系統呼叫的用途:在一段時間內,監聽使用者感興趣的檔案描述符上的可讀,可寫和異常等事件
select系統呼叫的原型:
#include
int select(int nfds,fd_set* readfds,fd_set* writefds,fd_set* exceptfds,struct timeval* timeout);
nfds引數指定被監聽的檔案描述符的總數,它通常被設定為select監聽的所有檔案描述符中的最大值加1,因為檔案描述符是從0開始計數的
readfds,writefds,exceptfds引數分別指向可讀,可寫和一場事件對應的檔案描述符集合
timeout引數用來設定select函式的超時時間,它是乙個timeval結構體型別(微秒級)的指標,採用指標引數是因為核心將修改它以告訴應用程式select等待了多久
select成功時返回就緒(可讀,可寫,異常)檔案描述符的總數。如果在超時時間內沒有任何檔案描述符就緒,select將返回0.select失敗時返回-1並設定errno.如果
等待期間,程式接受訊號,則select立即返回-1,並設定errno為eintr。
poll系統呼叫:在制定時間內輪詢一定數量的檔案描述符,已測試其中是否有就緒者
poll原型:
#include
int poll(struct pollfd* fds,nfds_t nfds,int timeout);
fds引數是乙個pollfd結構型別的陣列,它指定所有我們感興趣的檔案描述符上發生的可讀,可寫和異常等事件。
nfds引數指定被監聽事件集合fds的大小,其型別nfds_t定義:typedef unsigned long int nfds_t;
timeout引數指定poll的超時值,單位是毫秒。當timeout為-1時,poll呼叫將永遠阻塞,知道某個事件發生;當timeout為0時,poll呼叫立即返回
epoll系列系統呼叫:
epoll是linux特有的i/o復用函式
檔案描述符(用來標識核心中的事件表)的建立有epoll_creat來完成:
#include
int epoll_creat(int size)
操作epoll核心時間表:
#include
int epoll_ctl(int epfd,int op,int fd,struct epoll_event *event)
fd引數是要操作的檔案描述符,op引數則制定操作型別(epoll_ctl_add(往事件表中註冊fd上大的事件),epoll_ctl_mod(修改fd上的註冊事件),epoll_ctl_del(刪除fd上的註冊事件))
event引數指定事件,它是epoll_event結構指標型別
epoll_wait函式:
epoll系列系統呼叫的主要介面是epoll_wait函式,它在一段超時時間內等待一組檔案描述符上的事件
#include
int epoll_wait(int epfd,struct epoll_event* events,int maxevents,int timeout)
該函式成功時返回就緒的檔案描述符的個數,失敗時返回-1並設定errno
maxevent引數指定最多監聽多少個事件,它必須大於0
epoll對檔案描述符的操作有兩種模式:lt(電平觸發)模式(預設工作模式)和et(邊沿觸發)模式(高效工作模式)
lt:當epoll_wait檢測到其上有事件發生並將此事件通知應用程式後,應用程式可以不立即處理該事件,當應用程式下一次呼叫epoll_wait時,epoll_wait還會再次向應用程式通告此事件,直到該事件被處理
et:當epoll_wait檢測到其上有事件發生並將此事件通知應用程式後,應用程式必須立即處理該事件,因為後續的epoll_wait呼叫將不再向應用程式通知這一事件
epolloneshot事件
select,poll和epoll的區別:
i/o復用的高階應用一:非阻塞connect
connect出錯時的一種errno值:einprogress 這種錯誤發生在對非阻塞的socket呼叫connect,而連線又沒有立即建立時。
i/o復用的高階應用二:聊天室程式
客戶端功能:一是從標準輸入終端讀入使用者資料,並將使用者資料傳送至伺服器;二是往標準輸出終端列印伺服器程式傳送給它的資料。
伺服器的功能:接受客戶資料,並把客戶資料傳送給每乙個登陸到該服務區器上的客戶端(資料傳送者除外)
客戶端:使用poll同時監聽使用者輸入和網路連線,並利用splice函式將使用者輸入內容直接定向到網路連線上以傳送之,從而實現資料零拷貝,提高程式執行效率。
伺服器:使用poll同時監聽socket和連線socket,並且使用犧牲空間換取時間的策略來提高伺服器效能。
i/o復用的高階應用三:同時處理tcp和udp服務
超級服務xinetd:同時管理多個子服務,即監聽多個埠
xinetd採用/etc/xinetd.conf主配置檔案和.etc.xinetd.d目錄下的自配置檔案來管理所有服務
linux高效能伺服器程式設計 九 I O復用
第九章 i o復用 i o復用就是乙個執行緒可以同時監聽多個檔案描述符,提高程式效能。雖然i o復用可以同時監聽多個檔案描述符,但是它本身是阻塞的,如果多個檔案描述符準備就緒,如果不採取措施它仍然是序列工作的。所以只能通過多程序或者多執行緒來處理。linux下實現i o復用主要使用到 select ...
linux高效能伺服器程式設計
linux高效能伺服器程式設計 當當網 亞馬遜 目錄 第一章 tcp ip協議族 第二章 ip協議族 第三章 tcp協議詳解 第四章 tcp ip通訊案例 訪問internet 第五章 linux網路程式設計基礎api 第六章 高階io函式 第七章 linux伺服器程式規範 第八章 高效能伺服器框架...
linux 高效能伺服器程式設計
1.高效能定時器 時間輪,時間堆 處理超時時間,如nginx使用紅黑樹,找出最可能超時的事件 2.高效能伺服器程式框架 nginx 使用的是基於事件模型,epoll,不阻塞,非同步處理 兩種高效的事件處理模式 reactor模式 proactor模式 兩種高效的併發模式 半同步 半非同步模式 領導者...