select用法小结
select函数声明如下:
-
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
timeout 的使用
select函数的最后一个参数 timeout(注意它的数据类型)用来指定超时值,有下面三种情况:
-
若传入NULL,就是将select置于阻塞状态,一定等到监视文件描述符集合(file descriptor set)中某个文件描述符发生变化为止;
-
若将时间值设为0秒0毫秒,就变成一个纯粹的非阻塞函数,不管文件描述符是否有变化,都立刻返回继续执行,文件描述符无变化返回0,有变化返回一个正值;
-
timeout的值大于0,这就是等待的超时时间,即select在timeout时间内阻塞,超时时间之内有事件到来就返回了,否则在超时后不管怎样一定返回。
注意:在Linux下,select返回之后,timeout参数的值可能会被修改(告诉caller还剩下多少时间)。所以,为了安全起见,下次调用select之前,必须重新初始化timeout参数。
timeout的另外一个常见的用法是用来获得一个亚秒级的延时,下面是例子代码:
-
void mysleep(int sec, int usec)
-
{
-
struct timeval tm;
-
tm.tv_sec = sec;
-
tm.tv_usec = usec;
-
select(0, NULL, NULL, NULL, &tm);
-
}
fd_set 的使用
select的第2~4个参数的类型都是fd_set的指针,fd_set是一组文件描述符的集合,它用一位来表示一个fd。系统提供了4个宏对描述符集进行操作:
-
void FD_SET(int fd, fd_set *fdset); //设置文件描述符集fdset中对应于文件描述符fd的位(设置为1)
-
void FD_CLR(int fd, fd_set *fdset); //清除文件描述符集fdset中对应于文件描述符fd的位(设置为0)
-
void FD_ZERO(fd_set *fdset); //清除文件描述符集fdset中的所有位(把所有位都设置为0)
-
void FD_ISSET(int fd, fd_set *fdset); //在调用select后使用FD_ISSET来检测文件描述符集fdset中对应于文件描述符fd的位是否被置位。
注意:
1. select返回之后,fd_set的值可能会被修改(告诉caller那些FD已经ready或者有exception发生)。所以,下次调用select之前,必须重新初始化。
2. OS通过宏FD_SETSIZE来声明在一个进程中select所能操作的文件描述符的最大值(即fd_set包含的bit数),Linux下默认是1024。
阅读(1603) | 评论(0) | 转发(0) |