linux中select函数分析

文件头:#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环境高级编程(第二版)


你可能感兴趣的:(linux中select函数分析)