linux select

man select:

#include <sys/select.h>


#include <sys/time.h>


int select(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout);

select() and pselect() allow a program to monitor multiple file descriptors, waiting until one or more of the
file descriptors become "ready" for some class of I/O operation (e.g., input possible). A file descriptor is
considered ready if it is possible to perform the corresponding I/O operation (e.g., read(2)) without block‐
ing.

最后一个参数,他告知内核等待所指定描述字中的任何一个就绪可花多长时间。其timeval结构用于指定这段时间的秒数和微秒数。

    struct timeval
     {
             time_t tv_sec;
             time_t tv_usec;
     };
     这里第一个域的单位为秒,第二个域的单位为微秒。

nfds

需要检查的文件描述字个数(即检查到fd_set 的第几位),数值应该比三组fd_set中所含的最大fd值更大,一般设为三组fd_set中所含的最大fd值加1(如在readset, writeset,exceptset中所含最大的fd为5,则nfds=6,因为fd是从0开始的)。设这个值是为提高效率,使函数不必检查 fd_set的所有1024位。

 

readset

 来检查可读性的一组文件描述字。

 

writeset

用来检查可写性的一组文件描述字。

 

exceptset

用来检查是否有异常条件出现的文件描述字。(注:错误不包括在异常条件之内)

 

timeout

 

有三种可能:

1. timeout="NULL"(阻塞:直到有一个fd位被置为1函数才返回)

2. timeout所指向的结构设为非零时间(等待固定时间:有一个fd位被置为1或者时间耗尽,函数均返回)

3. timeout所指向的结构,时间设为0(非阻塞:函数检查完每个fd后立即返回)

select函数作用:在timeout时间内,不断测试不超过nfds 的所有fd,对于每一个接受到外部事件的fd, 将其在fd_set中的位置置1, 其余的没有接收到外部条件的fd位置置0,通外接下来的FD_ISSET进行测试,找到满足条件的所有fd。所以每次在调用select函数之前,要重新对fd_set进行赋值。

 

select函数返回值:

如果在timeout时间内,有fd满足条件,返回对应位仍然为1的fd的总数。

如果timeout时间用完了,也没有fd接收到外部事件,则返回0

出错的情况返回负数。

 

四个宏来操作: 完全一点 从accept开始.

fd_set set;

FD_ZERO(&set); /* 将set清零使集合中不含任何fd*/

FD_SET(fd, &set); /* 将fd加入set集合 */

FD_CLR(fd, &set); /* 将fd从set集合中清除 */

FD_ISSET(fd, &set); /* 测试fd是否在set集合中*/

过去,一个fd_set通常只能包含<32的fd(文件描述 字),因为fd_set其实只用了一个32位矢量来表示fd;现在,UNIX系统通常会在头文件中定义常量 FD_SETSIZE,它是数据类型fd_set的描述字数量,其值通常是1024,这样就能表示<1024的fd。根据fd_set的位矢量实 现,我们可以重新理解操作fd_set的四个宏:

fd_set set;

FD_ZERO(&set); /*将set的所有位置0,如set在内存中占8位则将set置为

00000000*/

 

FD_SET(0, &set); /* 将set的第0位置1,如set原来是00000000,则现在变为10000000,这样fd==1的文件描述字就被加进set中了 */

 

FD_CLR(4, &set); /*将set的第4位置0,如set原来是10001000,则现在变为10000000,这样fd==4的文件描述字就被从set中清除了 */


FD_ISSET(5, &set); /* 测试set的第5位是否为1,如果set原来是10000100,则返回非零,表明fd==5的文件描述字在set中;否则返回0*/

 

 

http://www.cnblogs.com/gentleming/archive/2010/11/15/1877976.html

http://blog.sina.com.cn/s/blog_5c8d13830100pwaf.html

http://blog.chinaunix.net/uid-26912934-id-3306946.html

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。