该函数允许进程指示内核等待多个事件中的任何一个发生,并且只有在一个或多个事件发生或经历一段指定的时间后才唤醒它。
我们调用select告知内核对哪些描述符感兴趣以及等待多长时间
1: #include<sys/select.h>2: #include<sys/time.h>
3: int select(int maxfd1,fd_set *readset,fd_set *writeset,fd_set *exceptset,const struct timeval *timeout);4: //返回:若有就绪描述符就为其数目,若超时则为0,出错为-1
中间的三个参数指定我们让内核测试读、写和异常条件的描述符。
我们使用以下函数来向描述符集中添加描述符:
void FD_ZERO(fd_set *fdset);
void FD_SET(int fd,fd_set *fdset);
void FD_CLR(int fd,fd_set *fdset);
void FD_ISSET(int fd,fd_set *fdset);
maxfd1参数指定待测试的描述符个数,它的值是待测试的最大描述符加1
函数返回后我们使用FD_ISSET来测试fd_set中的描述符,描述符内任何与未就绪描述符对应的位均返回时清0.
该函数的返回值表示所有描述符集已就绪的总位数
描述符就绪条件
(1)满足下面四个条件之一时,套接字准备好读
·该套接字接收缓冲区中的数据字节数大于等于套接字接收缓冲区低水位标记的当前大小
·该连接读半部关闭,接收到FIN
·该套接字为一个监听套接字,且已完成连接的个数不为0
·其上有一个错误待处理
(2)套接字准备好写
·该套接字发送缓冲区中的可用字节数大于等于套接字发送缓冲区低水位标记的当前大小
·该连接的写半部关闭.对这样的套接字写将产生SIGPIPE信号
·使用非阻塞式的connect的套接字已建立连接,或者connect已经以失败告终
·其上有一个套接字错误待处理
当某个套接字上发生错误时,它由select标记为既可以读又可以写
限制
select实现的并发服务器,能达到的并发数,受两方面限制
1、一个进程能打开的最大文件描述符限制。这可以通过调整内核参数。可以通过ulimit -n来调整或者使用setrlimit函数设置, 但一个系统所能打开的最大数也是有限的,跟内存大小有关,可以通过cat /proc/sys/fs/file-max 查看
2、select中的fd_set集合容量的限制(FD_SETSIZE,一般为1024) ,这需要重新编译内核。