文件头:#include<sys/select.h>
int select (int maxfdp1,fd_set * restrict readfds,fd_set *restrict writefds,fdset *restrict exceptfds,struct timeval *restrict tvptr);
返回值:准备就绪的描述符数,若超时则返回0,若出错,返回-1.但是要注意:如果在一个描述符上碰到了文件结尾处,则select认为改描述符是可读的,然后调用read,返回0。
注意:select中间有三个参数,如果三个指针都为空,则select提供了比sleep更为精确的计时器。
select 函数使我们可以执行I/O多路转接。传向select的参数告诉内核:
1.我们所关心的描述符;
2.对于每个描述符我们所关心的状态;
3.愿意等待多长时间(永远tvptr=NULL、固定值tvptr->tv_sec!=0||tvptr->tv_sec!=0、不等待tvptr->tv_sec==0&&tvptr->tv_usec==0)。
从select返回是,内核告诉我们:
对于读、写、异常这三个状态中的每一个,哪个描述符已经准备好了。”准备好“是指:对于readfds的read不会阻塞,则此描述符准备好。对于wirtefds的write操作不会阻塞,则此描述符准备好。exceptfds有未决异常,则准备好。
maxfdp1:select监视的文件句柄数,视进程中打开的文件数而定,一般设为要监视各文件中的最大文件号加一。 因为描述符编号是从0开始的,所以描述符(个)数要再编号基础上+1.
readfds:select监视的可读文件句柄集合。
writefds: select监视的可写文件句柄集合。
exceptfds:select监视的异常文件句柄集合。
每个描述符集存放在一个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表示可读写。
在声明了一个描述符集合,必须用FD_ZERO清除其所用位,然后在其中设置我们关心的各个位。
例如:
fd_set rset;
int fd;
FD_ZERO(&rest);
FD_SET(fd,&rset);
FD_SET(STDIN_FILENO,&rset);
if(FD_ISSET(fd,&rset)){
......}
参考文献:
UNIX环境高级编程(第二版)