I/O多路转接模型: 在这种模型下,如果请求的I/O操作阻塞,且它不是真正阻塞I/O,而是让其中的一个函数等待,在这期间,I/O还能进行其他操作。
#include <sys/select.h>
#include <sys/time.h>
int select(int maxfd, fd_set *readset, fd_set *writeset, fd_set *exceptionset,
const struct timeval
* timeout);
\\返回:就绪描述字的正数目,0——超时,-1——出错
参数解释:
maxfd 最大的文件描述符(其值应该为最大的文件描述符字 + 1)
readset 内核读操作的描述符字集合
writeset 内核写操作的描述符字集合
exceptionset 内核异常操作的描述符字集合
timeout 等待描述符就绪需要多少时间。
NULL代表永远等下去,一个固定值代表等待固定时间,
0代表根本不等待,检查描述字之后立即返回。
其中 readset、writeset、exceptionset 都是 fd_set 集合。该集合的相关操作如下:
void FD_ZERO(fd_set *fdset); /* 将所有fd清零 */
void FD_SET(int fd, fd_set *fdset); /* 增加一个fd */
void FD_CLR(int fd, fd_set *fdset); /* 删除一个fd */
int FD_ISSET(int fd, fd_set *fdset); /* 判断一个fd是否有设置 */
|
select函数中的 timeout 是一个 struct timeval 类型的指针,该结构体如下: |
struct timeval
{
long tv_sec; /* second */ //秒
long tv_usec; /* microsecond */ //微秒
};
|
流程:
fd_set readset;
FD_SET(0,&readset);
FD_SET(fdr,&readset);
int ret=select(fdr+1,&readset,NULL,NULL,NULL);
if(ret >0)
{
if(FD_ISSET(0,&readset))
{
}
if(FD_ISSET(fdr,&readset))
{
}
}
|
select 监控哪些描述符可以读
a.c | b.c |
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<sys/time.h>
#include<unistd.h>
#include<stdio.h>
#include<strings.h>
#include<string.h>
int main(int argc,char** argv)
{
int fdw=open(argv[1],O_RDWR);
int fdr=open(argv[2],O_RDWR);
printf("fdw=%d fdr=%d\n",fdw,fdr);
char buf[128]="";
fd_set rdset;
int ret;
while(1)
{
FD_ZERO(&rdset);
FD_SET(0,&rdset);
FD_SET(fdr,&rdset);
ret=select(fdr+1,&rdset,NULL,NULL,NULL);
if(ret>0)
{
if(FD_ISSET(0,&rdset))
{
bzero(buf,sizeof(buf));
read(0,buf,sizeof(buf));
write(fdw,buf,strlen(buf)-1);
//从控制终端读的时候,回车也会读进去,所以要-1去掉回车
}
if(FD_ISSET(fdr,&rdset))
{
bzero(buf,sizeof(buf));
read(fdr,buf,sizeof(buf));
printf("b:%s\n",buf);
}
}
}
return 0;
}
|
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<sys/time.h>
#include<unistd.h>
#include<stdio.h>
#include<strings.h>
#include<string.h>
int main(int argc,char** argv)
{
int fdr=open(argv[1],O_RDWR);
int fdw=open(argv[2],O_RDWR);
printf("fdr=%d fdw=%d\n",fdr,fdw);
char buf[128]="";
fd_set rdset;
int ret;
while(1)
{
FD_ZERO(&rdset);
FD_SET(0,&rdset);
FD_SET(fdr,&rdset);
ret=select(fdr+1,&rdset,NULL,NULL,NULL);
if(ret>0)
{
if(FD_ISSET(0,&rdset))
{
bzero(buf,sizeof(buf));
read(0,buf,sizeof(buf));
write(fdw,buf,strlen(buf)-1);
}
if(FD_ISSET(fdr,&rdset))
{
bzero(buf,sizeof(buf));
read(fdr,buf,sizeof(buf));
printf("a:%s\n",buf);
}
}
}
return 0;
}
|