一、函数介绍
头文件:
#include <sys/select.h>
函数原型:
int select(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout);
参数介绍:
1.int nfds:待测试的描述符个数,它的值是待测试的最大描述符加1
2.fd_set *readfds:指向fd_set结构的指针,这个集合中包括文件描述符,我们是要监视这些文件描述符的读变化的,就是关注是否可以从这些文件中读取数据,如果这个集合中有一个文件可读,select就会返回一个大于0的值,表示有文件可读,如果没有可读的文件,则根据timeout参数再判断是否超时,若超出timeout的时间,select返回0,若发生错误返回负值。可以传入NULL值,表示不关心任何文件的读变化。
3.fd_set *writefds:指向fd_set结构的指针,这个集合中包括文件描述符,我们是要监视这些文件描述符的写变化的,就是关注是否可以从这些文件中写入数据,如果这个集合中有一个文件可写入,select就会返回一个大于0的值,表示有文件有写入权限,如果没有可一写的文件,则根据timeout参数再判断是否超时,若超出timeout的时间,select返回0,若发生错误返回负值。可以传入NULL值,表示不关心任何文件的读变化。
4.fd_set *exceptfds:这个参数用来检测文件有无异常情况发生
5.struct timeval *timeout:
这个地方根据填入的值不同,可以设置三种select的工作方式
方式一:此处填入NULL,使用阻塞的方式,一直到检测到文件描述符有变化才返回·。
方式二:若填入0秒0毫秒,就变成非阻塞函数,不管文件描述符是否有变化,都会立刻返回继续执行,文件无变化返回0,有变化返回一个正值。
方式三:timeout的值大于0,该值就是等待的超时时间,即select在timeout时间内阻塞,超时时间之内有事件到来就返回了,否则在超时后不管怎样一定返回,文件无变化返回0,有变化返回一个正值。
返回值:
负值:select错误;
正值:某些文件可读写或出错;
0:等待超时,没有可读写或错误的文件。
返回的错误码介绍:
EBADF 文件描述词为无效的或该文件已关闭
EINTR 此调用被信号所中断
EINVAL 参数n为负值。
ENOMEM 核心内存不足
二、select用到的函数
FD_CLR(inr fd,fd_set* set);//用来清除描述词组set中相关fd的位
FD_ISSET(int fd,fd_set *set);//用来测试描述词组set中相关fd的位是否为真
FD_SET(int fd,fd_set*set);//用来设置描述词组set中相关fd的位
FD_ZERO(fd_set *set);//用来清除描述词组set的全部位
三、用到的结构体(下面是man手册截取的时间结构体的介绍)
The timeout
The time structures involved are defined in <sys/time.h> and look like
struct timeval {
long tv_sec; /* seconds */
long tv_usec; /* microseconds */
};
and
struct timespec {
long tv_sec; /* seconds */
long tv_nsec; /* nanoseconds */
};
在设置超时时间时可以参考下面的方式初始化参数
struct timeval tv; //声明结构体
tv.tv_sec = 2;//秒
tv.tv_usec = 33;//毫秒
select(0, NULL, NULL, NULL, &tv);
//这样一个简单的定时就设置好了