Linux 网络编程详解十
select int select(int nfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds, struct timeval *timeout); 参数nfds:readfds集合内文件描述符的最大值(文件描述符的值)加1 参数readfds:用户关心的读文件描述符集合 返回值:如果成功,返回所有sets(所有即readfds,writefds,exceptfds)中描述符的个数,如果超时,返回0,如果出错,返回-1 fd_set本质上是一个状态字技术(和PCB中屏蔽状态字类似的概念)
void FD_CLR(int fd, fd_set *set); --从集合内把一个描述符移除 int FD_ISSET(int fd, fd_set *set); --测试文件描述符fd是否在集合内 void FD_SET(int fd, fd_set *set); --把一个描述符加入集合 void FD_ZERO(fd_set *set); --清空描述符集合
select()实现说明 调用select时通过参数告诉内核,用户感兴趣的IO描述符以及对应的IO状态(输入,输出或错误) select机制有Linux内核支持,不需要上层应用通过系统调用read轮询的去访问内核中的缓存(内核直接访问缓存数据速度会更快), 一旦检测到一个I/O或者多个I/O有我们感兴趣的事件发生,select函数将返回,返回值为检测到的事件个数。 此时上层应用再调用read函数读取数据
注意:select机制并不一定需要设置I/O描述符非阻塞,select复用模型相当于提前阻塞,等到select返回时,再调用read就不会阻塞了。
select返回值三态 1.若timeout时间到(超时),没有检测到读写事件,ret返回0 2-1.若ret返回-1并且errno==EINTR 说明select的过程中被别的信号中断(可中断睡眠原理) 2-2.若ret返回-1,select出错 3.若ret返回值>0 表示有事件发生,返回发生事件的个数