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 代表根本不等待, 检查描述字之后立即返回
其中 readsetwritesetexceptionset 都是 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 函数之前, 首先要使用 FD_ZERO 和 FD_SET 来初始化文件描述符集, 在使用 select 函数时, 可循环使用 FD_ISSET 测试描述符集, 在执行完对相关文件描述符之后, 使用 FD_CLR 来清除描述符集 (也可以直接用 FD_ZERO 直接全部清零)
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;
- }
来源: https://www.cnblogs.com/meihao1203/p/8443979.html