IO多路复用--select

IO多路复用,就是在多个文件描述符上阻塞,并在其中某个fd能用的时候收到通知。

其设计原则是

1: 任何文件描述符准备好IO的时候就告诉我;

2.在没有文件描述符就绪的时候睡觉,这样也不会因为IO而把程序憋死。

3. 在不阻塞的情况下处理所有有收到通知的fd。

常见的方式就是select,poll , epoll。它们有个好处就是可以设置超时,尤其在通讯的IO方面很方便。

 

函数的造型是 int select(int n,fd_set *readfds,fd_set *writefds,fd_set *errorfds,struct timeval *timeout);

它包含了三个集合,readfds,writefds,errorfds,用户把想监听的fd放入其中,想监听可读信号就仍readfds里面。

然后当你输入的时候内核就通知,用这个宏FD_ISSET(fd,&readfds)来看看fd在不在这个集合里面要在,妥了,直接开始读

示例程序:它监听输出和输入,但是只有你输入一个啥玩意的时候程序才接到消息,不输入它里面没东西,就没法读。

#include<stdio.h>    //printf

#include<sys/time.h>    //struct timeval


#include<sys/select.h>

#include<unistd.h>   //STDOUT_FILENO

#define TIMEOUT  5

#define BUF_LEN  1024

int main(void)

{

struct timeval tv;

fd_set readfds;

fd_set writefds;

int ret;

FD_ZERO(&readfds);



FD_SET(STDIN_FILENO,&readfds);

tv.tv_sec = TIMEOUT;

tv.tv_usec = 0;

int i = 0;


ret = select(STDIN_FILENO+1,&readfds,NULL,NULL,&tv);

if(ret == -1){

perror("select");

return 1;

}else if(!ret){

printf("%d second elapsed.\n",TIMEOUT);

return 0;

}

if(FD_ISSET(STDIN_FILENO,&readfds)){

char buf[BUF_LEN+1];

int len;

len = read(STDIN_FILENO,buf,BUF_LEN);

if(len == -1){

perror("read");

return 1;

}

if(len){

buf[len]='\0';

printf("read : %s\n",buf);

}




return 0;

}


但是select有它性能上的不足,而且也有监听文件上限的不足,当fd的值超过1024限制时,就必须修改FD_SETSIZE的大小,当监听的文件太多了,复制,遍历一遍的开销也不小。但是它的跨平台性是最好的,若一定要用这个,就用多线程来做,每个线程里面分配小于1024个。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值