系统提供select函数来实现多路复用输入/输出模型。select系统调用是用来让我们的程序监视多个文件句柄的状态变化的。

select:该函数允许进程指示内核等待多个事件中的任何一个发生,并只在有一个或多个事件发生或经历一段指定的时间后才唤醒它。

参数含义:
timeout:它告知内核等待所制定描述符中的任何一个就绪可在多长时间,其timeval结构用于指定这段时间的秒数和微妙数。
struct timeval
{
long tv_sec;//seconds
long tv_usec;//microseconds
}
有三种情况:
永远等待下去:仅在有一个描述符准备好I/O时才返回,为此,我们把该参数设为NULL.
等待固定时间:在有一个描述符准备好I/O时返回,但是不超过由该参数所指向的timeval结构中指定的秒数和微妙数。
根本不等待:检查描述符后立即返回,这称为轮询,为此该参数必须指向一个timeval结构,而且其中的定时器值必须为0;
前两种情形的等待通常会被进程在等待期间捕获的信号中断,并从信号处理函数返回。
注:有的Linux会在select函数返回时修改timeval结构,从移植性考虑,我们应假设timeval结构在函数返回时未定义,因而每次调用select前都得对它进行初始化。
中间的三个参数readset,writeset和exceptset制定我们要内核测试读,写,异常条件的描述符。
异常原因:
1.某个套接字的带外数据的到达
2.某个已置为分组模式的伪终端存在可从其主端读取的控制状态信息
select使用描述符集,通常是一个×××数组,其中每个整数中每一位对应一个描述符
四个宏:
maxfd:待测试描述符个数:待测试描述符加1,描述符1,2...到maxfd-1均被测试。
<sys/select.h>中FD_SETSIZE常值是数据类型fd_set中描述符总数,其值通常是1024.
select函数修改三个描述符集,参数是值-结果参数,调用时,是关心描述符值。返回时,指示那些描述符已就绪。
描述符中任何与未就绪描述符对应的位返回时均被清为0,因此每次重调时,再次把所有描述符集中所关心的位置1.
返回值:大于0:所有描述符中已就绪的总位数。
等于0:超时
-1:出错
就绪条件:

//监视输入输出
#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<sys/time.h>
#include<sys/select.h>
#include<string.h>
int main()
{
int read_fd=0;
int write_fd=1;
fd_set reads;
fd_set writes;
FD_ZERO(&reads);
FD_ZERO(&writes);
struct timeval _timeout={5,0};
int ret=-1;
int max_fd=write_fd;
char buf[1024];
while(1)
{
FD_SET(read_fd,&reads);
FD_SET(write_fd,&writes);
_timeout.tv_sec=5;
_timeout.tv_usec=0;
ret=select(max_fd,&reads,&writes,NULL,&_timeout);
switch(ret)
{
case -1://error
perror("select");
break;
case 0://time out
printf("time is out...\n");
break;
default://normal
{
ssize_t _s;
if(FD_ISSET(read_fd,&reads))
{
_s=read(0,buf,sizeof(buf)-1);
buf[_s]='\0';
if(strncmp(buf,"quit",4)==0)
{
printf("quit\n");
return 1;
}
printf("echo: %s",buf);
}
if(FD_ISSET(write_fd,&writes))
{
strcpy(buf,"hello world");
printf("show: %s\n",buf);
}
}
break;
}
}
return 0;运行截图:

实现TCP通信,处理任意个客户的单进程,而不是为每一个客户派生一个子进程。
创建监听套接字并初始化:调用socket,bind,listen,唯一描述符是监听描述符初始化数据结构。
阻塞于select:select等待某个事件发生或新客户连接的建立或是数据,FIN或RST的到达。
accept新连接
如果监听套接字变为可读,那么已建立一个新的连接,我们调用accept并更新相应数据结构。使用fds数组中第一个未用项记录这个已连接描述符。
检查现有连接
另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。