select用法
select的函数格式:
int select(int maxfdp,fd_set *readfds,fd_set *writefds,fd_set *errorfds,struct timeval *timeout);
各个参数的用法:
int maxfdp:是一个整数值,是指集合中所有文件描述符的范围,即所有文件描述符的最大值加1,不能错!在Windows中这个参数的值无所谓,可以设置不正确。
struct fd_set:可以理解为一个集合,这个集合中存放的是文件描述符(file descriptor),即文件句柄。fd_set集合可以通过一些宏由人为来操作。
FD_ZERO(fd_set *fdset):清空fdset与所有文件句柄的联系。
FD_SET(int fd, fd_set *fdset):建立文件句柄fd与fdset的联系。
FD_CLR(int fd, fd_set *fdset):清除文件句柄fd与fdset的联系。
FD_ISSET(int fd, fdset *fdset):检查fdset联系的文件句柄fd是否可读写,>0表示可读写。
struct timeval:用来代表时间值,有两个成员,一个是秒数,另一个是毫秒数。
1、若将NULL以形参传入,即不传入时间结构,就是将select置于阻塞状态,一定等到监视文件描述符集合中某个文件描述符发生变化为止;
2、若将时间值设为0秒0毫秒,就变成一个纯粹的非阻塞函数,不管文件描述符是否有变化,都立刻返回继续执行,文件无变化返回0,有变化返回一个正值;
3、timeout的值大于0,这就是等待的超时时间,即select在timeout时间内阻塞,超时时间之内有事件到来就返回了,否则在超时后不管怎样一定返回。
struct timeval{
long tv_sec; /*秒 */
long tv_usec; /*微秒 */
}
select优点:
多路转接,效率高
select缺点:
- 每次调用select,都需要手动设置fd_set集合,非常不便
- 需要将集合从用户态拷贝到内核态,开销大
- 调用select,遍历整个集合,开销大
- fd_set集合有最大上限