IO多路轉接之select

2021-08-20 17:33:38 字數 1864 閱讀 4613

系統提供select函式來實現多路轉接。

呼叫select函式介面的特點:一次需要等待多個檔案描述符。

select函式原型:

#include #include #include int select(int nfds, fd_set *readfds, fd_set *writefds,  fd_set *exceptfds, struct timeval *timeout);
nfds:要關心的最大檔案描述符+1,限定了檔案描述符的遍歷區間。

乙個檔案描述符需要關心三個事件:

讀事件寫事件

異常事件

fd_set實際上是乙個位圖

timeval結構體

timeout:表示select可以每隔多久時間醒過來等待一次,如果所期望的時間沒有發生,就去忙別的。

使用select編寫簡單的伺服器:

#include#include#include#include#include#include#include#include#define max_fd sizeof(fd_set)*8//最多可監聽多少個檔案描述符

#define init -1

int starup(int port)

int opt=1;

setsockopt(sock,sol_socket,so_reuseaddr,&opt,sizeof(opt));

struct sockaddr_in local;

local.sin_family=af_inet;

local.sin_port=htons(port);

local.sin_addr.s_addr=htonl(inaddr_any);

if(bind(sock,(struct sockaddr*)&local,sizeof(local))<0)

if(listen(sock,5)<0)

return sock;

}void array_init(int* fd_array,int num)

}void service(int* fd_array,int num,fd_set* rfds)

if(array_add(fd_array,num,new_sock)<0)

}else;

ssize_t s=read(fd,buf,sizeof(buf)-1);

if(s>0)else if (s==0)else}}

}}int main(int argc,char* argv)

//建立監聽套接字

int listen_sock=starup(atoi(argv[1]));

int fd_array[max_fd];

//初始化陣列

array_init(fd_array,max_fd);

//將監聽到的新連線加入到陣列裡

array_add(fd_array,max_fd,listen_sock);

fd_set rfds;//位圖

int max_fd=0;

for(;;);

//清空位圖

fd_zero(&rfds);

//將陣列中的檔案描述符新增到位圖中

max_fd=set_rfds(fd_array,max_fd,&rfds);

switch(select(max_fd+1,&rfds,null,null,&timeout))

}}

select缺點:

每次呼叫select,都要手動設定fd集合。

select限定了可接收的檔案描述符上限。

I O多路轉接之select

什麼是i o多路轉接技術 先構建一張有關描述符的列表,然後呼叫乙個函式,直到這些描述符中的乙個已準備好進行i o時,該函式才返回,在返回時,他告訴程序哪些描述符已準備好可以進行i o。上述呼叫的函式,有select,poll,pselect及poll的增強版epoll等,本文主要介紹select。函...

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

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