I O多路轉接之select

2021-07-17 04:21:44 字數 1822 閱讀 6437

什麼是i/o多路轉接技術:

先構建一張有關描述符的列表,然後呼叫乙個函式,直到這些描述符中的乙個已準備好進行i/o時,該函式才返回,在返回時,他告訴程序哪些描述符已準備好可以進行i/o。

上述呼叫的函式,有select,poll,pselect及poll的增強版epoll等,本文主要介紹select。

函式原型:

int select(int maxfdp1,fd_set *restrict readfds,fd_set *restrict writefds,fd_set *restrict rxceptfds,struct timeval *restrict tvptr);

返回值:返回-1時,表示出錯

返回0時,表示沒有描述符準備好,並把描述符集清0

返回正整數時,表示已經準備好的描述符數之和,並清零除準備好的描述符之外的其它位

引數介紹:

maxfdp1:取描述符中最大的乙個並+1。也可將其設定為fd_setsize,即最大的描述符數(一般為1024)。但多數時間用不到這麼多的描述符。

readfds,writefds,rxceptfds:指向描述符集的指標,放入的是我們關心的狀態是可讀或可寫或處於異常的描述符。描述符集內為每乙個描述符保持一位,即放入的描述符僅佔一位。

tvptr:指向timeval結構體的指標,指定願意等待的時間。

struct timeval{

long tv_sec;//秒

long tv_usec;//毫秒

}當tvptr==null時,則永遠等待,如果有描述符準備好可讀或可寫或異常時,則中斷此永遠等待,select返回乙個值。

當tvptr->tv_sec==0 && tvptr->tv_usec==0時,則永遠不等待,獲得所有描述符的狀態後立即返回。這是獲得多個描述符的狀態而不阻塞select的輪詢方法。

當tvptr->tv_sec=指定的秒數 || tvptr->tv_usec=指定的毫秒數,則等待指定的時間,當指定的描述符準備好或超時,則立即返回,如果超時卻沒有描述符準備好,則返回0。

實現過程:

核心從0到maxfdp1遍歷一遍描述符,當某一描述符集內的某一描述符準備好時,返回1,若乙個描述符同時存在於兩個描述符集內,且都準備好,則直接返回2。

介面函式:

select的介面共有4個函式

int  fd_isset(int fd,fd_set *fdset);//從select返回時,用來測試該集中的乙個給定位是否仍舊設定。

void fd_clr(int fd,fd_set *fdset);//清除指定集中的指定位

void fd_set(int fd,fd_set *fdsset);//將指定描述符加入到指定描述符集中

void fd_zero(fd_set *fdset);//將指定的描述符集所有位設定為0

**一般框架:

fd_set readset;//此處並沒有定義指向結構體的指標,而是直接定義型別為fd_set的結構體

fd_set rset;

intmaxfd;

......

......

......

fd_zero(&readset);//函式原型此處操作的是指標,所以我們取結構體的首位址

fd_set(server_fd,&readset);

fd_set(other_fd,&readset);

for( ; ; )

else if(fd==other_fd)

......

}......}}

} 總結:

select的缺點很明顯,在高併發下,效率低,且最大併發數受限。但在低併發下且描述符活躍時,select效率也與epoll相差不大。

I O多路轉接之select

下面的巨集提供了處理fd set的這三種描述集的方式 fd clr inr fd,fd set set 用來清除描述片語set中相關fd 的位 fd isset int fd,fd set set 用來測試描述片語set中相關fd 的位是否為真 fd set int fd,fd set set 用來...

IO多路轉接之select

系統提供select函式來實現多路轉接。呼叫select函式介面的特點 一次需要等待多個檔案描述符。select函式原型 include include include int select int nfds,fd set readfds,fd set writefds,fd set exceptf...

IO多路轉接之select

阻塞io,在核心將資料準備好之前,系統會一直在等待,所有的套接字,預設都是阻塞方式 非阻塞io 如果核心還沒有將資料準備好,系統會呼叫仍然直接返回,並且返回ewouldblock錯誤碼,非阻塞io需要程式設計師迴圈的方式反覆嘗試讀寫檔案描述符,看資料是否準備好,這個過程稱為輪詢,這對cpu來說是很大...