本文為unp第6章學習筆記
一, select函式
#include
int select(int maxfd,fd_set* readset, fd_set* writeset, fd_set* exceptset, const struct timeval* timeout);
引數:maxfd: select管理的最大fd+1, 也就是說你必須自己算出最大的fd是多大
readset: 需要監控可讀的fd集合, 只要read/accept操作不會阻塞,就算可讀狀態, 包括對方已關閉(返回0),套接字出錯(返回負值),可讀(返回正值),有新連線(可accept)
writeset 需要監控可寫的fd集合,wrte操作不阻塞或非阻塞socket中connect已完成,就算可寫, 包括對方已關閉(sigpipe訊號),套接字出錯(返回負值),可寫, connect完成或出錯
exceptset 異常條件的fd集合,通常用不到, 注意socket出錯不算異常,而算是可讀或可寫
timeout: null:阻塞 為0的timeval: 立刻返回 非0的timeval: 帶定時器的阻塞
返回值:
>0: 就緒fd的數目
=0:超時
<0:出錯
二, fd_set相關巨集
fd_set用來表示一組fd集合, 一般是乙個long int陣列,可能的實現如下:
struct fd_set;
fd_set用每個位是1/0來記錄fd, 16個long int共有 16*64=1024位, 因此select只能處理最多1024個fd.
fd_set可能有不同的實現,但我們只需要關注這4個操作fd_set的巨集:
void fd_zero(fd_set* fdset);
//將整個fdset置0
void fd_set(int fd,fd_set* fdset);
//將某個fd加到fdset中
void fd_clr(int fd,fd_set* fdset);
//將某個fd從fdset中刪除
int fd_isset(int fd,fd_set* fdset);
//判斷某個fd是否在fdset中
三,select的性質
1,select最多隻支援1024個fd
2,每次select完成後會清空各fd_set種未就緒的fd,因此:
1,你每次select都要重新用fd_set加入fd
2,你需要對每個監控的fd呼叫一次fd_isset來判斷這個fd是否就緒
這些性質導致select的效能隨監控fd數量的增加線性下降, 更好也更流行的方法是epoll, 同時epoll的使用也更為簡單
四,用select實現的單執行緒伺服器示例:
**不夠簡潔,總之:1,有乙個資料結構記錄所監控的fd 2,計算maxfd
//...... init listenfd
setconnected_fds;
fd_set rset;
int nready;
int maxfd;
vectordel_fds;
while(1)
nready = select(maxfd+1,&rset,0,0,0);
if(fd_isset(listenfd,&rset))
connected_fds.insert(newfd);
}for(set::iterator iter=connected_fds.begin();iter!=connected_fds.end();iter++)
else if(ret <0)else}}
for(vector::iterator iter=del_fds.begin();iter!=del_fds.end();iter++)
del_fds.clear();
}
五,poll函式
#include
int poll(struct pollfd* fdarray, unsigned long nfds, int timeout);
引數:fdarray: 記錄fd資訊的陣列指標
nfds: 陣列長度
timeout: 作用與select最後乙個引數相同,注意這是乙個int,單位是毫秒. inftim:阻塞 0 非阻塞 >0:超時時間
poll提供的功能與select基本相同, 可以看錯是使用了另一種方式組織管理fd資訊,
struct pollfd;
如果fd<0, 那麼poll將自動忽略這個pollfd
六, poll的性質
因為poll函式管理fd的資料是由使用者自由分配的陣列,因此poll沒有管理fd數量的限制
poll不會修改未就緒的pollfd資訊, 但你仍需需要檢查每個pollfd的revents來判斷該fd是否就緒
比較而言, select的使用比poll更為廣泛. 不過相比之下,新一代的epoll有明顯的優勢
TCP IP網路程式設計 IO復用
引入復用技術,可以減少程序數,無論連線多少客戶端,提供服務的程序只有乙個。select函式可以實現io復用,它可以將多個檔案描述符集中到一起統一監視 是否存在套接字接收資料?無需阻塞傳輸資料的套接字有哪些?哪些套接字發生了異常?下面是具體用例 復用 時分復用 頻分復用 使用select函式完成io復...
linux系統I O復用技術之一 select
1.標頭檔案 include include include 2.引數說明 int select int maxfdp,fd set readfds,fd set writefds,fd set errorfds,struct timeval timeout 先說明兩個結構體 第一,struct f...
linux系統I O復用技術之一 select
include include include 2.引數說明 int select int maxfdp,fd set readfds,fd set writefds,fd set errorfds,struct timeval timeout 先說明兩個結構體 第一,struct fd set可以...