记录自己的linux学习之旅。
参考文章:
http://blog.csdn.net/leo115/article/details/8097143
首先大概谈一下对select的理解,select用于检测传入的文件描述符的状态,是一个多路I/O就绪通知的一个方法。
select 函数原型:
#include<sys/select.h>
int select(int maxfd,fd_set* read,fd_set* write,fd_set* exception,struct timeval* timeout);
我们一一阐述它的返回值和参数
返回值: int 型的整数。
-1:发生错误
0 : 没有符合条件的描述符或者超时
大于0的整数:返回的是符合条件的描述符的数目
maxfd:int 型的整数
它用于指定所有需要被检测的文件描述符的范围,它的取值是 MAX(fd)+1。
先解释一下 fd_set : 可以理解为一个bit类型的数组,比如说我要检测某个fd的状态,就将该数组中第fd位 置 1。关于fd_set的操作 待会还会细说一下。
fd_set* read:
为NULL时,表示对读状态不在意
非NULL时,会对传入的fd的读状态检测,如果该fd可读,则將该位保持不变(即依然为1),如果该fd的不可读则将改为清零。
fd_set* write 和 fd_set* exception 同理,分别检测fd的写状态和异常状态。
struct timeval* timeout:
首先看一下timeval的声明。
struct timeval{
long tv_sec; //秒
long tv_usec;//微秒
}
timeval表示超时时间,它的取值有如下几种情况。
为NULL时,等待无限长的时间,进入阻塞状态,直到检测到相应的状态变化或者被信号中断位置,此时就像阻塞式的调用socket的accept,recv,read之类的函数。
2个域均为0时,不等待任何时间,轮询完传入的所有描述符后立即返回。
不为0时,如果没有描述符符合检测状态,则等待这么长的时间,直到有相应的fd就绪,则返回。或者是超时返回,此时返回0。
接下来谈一谈 fd_set的使用方法。
首先看一下与之相关的几个操作而定义的宏:
#include<sys/select.h>
FD_ZERO(fd_set* set); //将一个文件描述符集合清零
FD_CLR(int fd,fd_set* set);//将该文件描述符集合的第fd位清零
FD_SET(int fd,fd_set* set);//将该文件描述符集合的第fd位置1
FD_ISSET(int fd,fd_set* set);//检测该文件描述符的第fd位的值 返回1 该fd符合当前检测状态,0即不符合。
对于fd_set的使用,总是要先将其清零,再set相应的fd,之后调用select对其进行检测,最后用ISSET来检测符合条件的fd。使用样例这里就不提供了。