多路复用I/O

20 篇文章 0 订阅
15 篇文章 0 订阅

多路复用IO主要的实现在于int select(int maxfd,fd_set *readset,fd_set *writeset,fd_set *except_set,const struct timeval *timeout)函数。

一般我们在readset,writeset和exceptset中只设置一个,其余两个为NULL,系统监视从0到maxfd 的所有文件描述符,当任一个文件描述符其在相应的set中就绪时,select函数返回。此时的readset,writeset,exceptset的 内容被设置成发生事件的文件描述符。

所以一般先用一个fd_set allset来保存所有的fd,每次调用select函数时,先把allset赋值给想要的set(readset,writeset, exceptset),然后用相应的set作参数调用select。select并不返回哪个fd就绪,所以要想知道到底是哪个fd就绪,要用 FD_ISSET(int fd,fd_set *fdset)来测试,一个不错的方法就是每生成一个fd就保存到数组中,然后用一个循环看看是哪个fd就绪了。

fd_set allset;//所有的fd
fd_set rset;//用作参数,一般调用select后其值都会改变。
int fds[20];
int maxid;
FD_ZERO(&allset);
int fd=createfd();//一个能返回文件描述符的函数,当然这里没有实现。
FD_SET(fd,&allset);//加入到allset中
for(int i=0;i<20;i++)
 fds[i]=-1;//后来不断的加入文件描述符,为了不覆盖原有的值,设一个标志。
maxid=fd;
while(1){
 rset=allset;
 select(maxfd,&rset,NULL,NULL,NULL);
 for(int i=0;i<20;i++)
  if(FD_ISSET(fds[i],&rset)){
   chuli();
   break;
  }
 fd=createfd();
 for(int i=0;i<20;i++)
  if(fds[i]<0){ 
   fds[i]=fd;
   FD_SET(fd,&allset);
  }
}

当socket()->bind()->listen之后,如果有如下的代码

while(1){
 select(listen_fd,&rset,NULL,NULL,&tv);
 if(FD_ISSET(listen_fd,&rset)){
  accept(....);
 }

if(FD_ISSET(fd,&rset)){
read(....);
}
}
则当没有连接进入时,不会执行if内部的语句块,也就是说不会产生accept阻塞。
当没有文件描述符可读时,不会执行read,也就是说read不会阻塞。

转载: http://blog.163.com/dlx1986@126/blog/static/2625054920074216448888/


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值