FD_set FD_zero
select()机制中提供一fd_set的数据结构,实际上是一long类型的数组,每一个数组元素都能与一打开的文件句柄(不管是socket句柄, 还是其他文件或命名管道或设备句柄)建立联系,建立联系的工作由程序员完成,当调用select()时,由内核根据IO状态修改fe_set的内容,由此 来通知执行了select()的进程哪一socket或文件可读。 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集合中*/
select函数 系统提供了select函数实实现多路复用输入/输出模型。原型
#include <sys/time.h>
#include <unistd.h>
int select(int maxfd, fd_set *rdset, fd_set *wrset, fd_set *exset, struct timeval *timeout);
参数maxfd是需要监视的最大的文件描述符值+1;rdset,wrset,exset分别对应于需要检测的可读文件描述符的集合。可写文件描述符的集合。
及异常文件描述符的集合。struct timeval结构用于描述一段时间长度,如果在这个时间内, 需要监视的描述符
没有事件发生则函数返回,返回值为0。
FD_ZERO,FD_SET, FD_ISSET,FD_CLR:
FD_ZERO(fd_set *fdset)将指定的文件描述符清空,在对文件描述符集合进行设置前,必须对其进行初始化。如不清空,由于在系统分配
内存空间后,通常并不做清空处理,所以结果是不可知的。
FD_SET(fd_set *fdset)用于文件描述符集合中增加一个新的文件描述符。
FD_CLR(fd_set *fdset)用于文件描述符集合中删除一个文件描述符。
FD_ISSET(int fd, fd_set *fdset)用于测试指定的文件描述符是否在该集合中。
struct timeval {
long tv_sec; //second
long tv_usec; // mini second
}
timeout设置情况
null:select将一直被阻塞,直到某个文件描述符发生了事件。
0:仅检测描述符集合的状态,然后立即返回,并不等待外部事件的发生。
特定的时间值:如果在指定的时间段内没有事件发生,select将超时返回。
('fd_set')是一组文件描述符(fd)的集合,由于fd_set类型的长度在不同平台上不同,因此应用一组标准的宏定义来处理此类变量。
fd_set set;
FD_ZERO(&set); /*将set清零*/
FD_SET(fd, &set);/*将fd加入到set中*/
FD_CLR(fd, &set);/*将fd从set中清除*/
FD_ISSET(fd, &set);/*如果fd在set中为真*/
在过去,一个fd_set通常只能包含少于等于32个文件描述符。因为fd_set其实只用了一个int的比特矢量来实现。在大多数情况下,
检查fd_set能包括任意值的文件描述符是系统的责任,但是确定你的fd_set到底能放多少有时要检查或修改宏FD_SETSIZE的值。*这个值是系统相关的*
同时检查你的系统中的select()的man手册。有一些系统对多于1024个文件描述符的支持有问题。
fd_set具体是怎样实现的。
#define FD_SETSIZE 1024
typedef unsigned long fd_mask;
#define NBBY 8 /*number of bits in a btye */
#define NFDBITS(sizeof(fd_mask) * NBBY) /* bits per mask */
#define howmany(x,y) (((x) + ((y)-1))/(y))
typedef struct fd_set {
fd_mask fds_bits[howmany(FD_SETSIZE, NFDBITS)];
} fd_set;
#define _fdset_mask(n) ((fd_mask)1<<;((n)%NFDBITS))
#define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= _fdset_mask(n))
#define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~_fdset_mask(n))
#define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] &_fdset_mask(n))
#define FD_COPY(f,t) bcopy(f,t,sizeof(*(f)))
#define FD_ZERO(p) bzero(p, sizeof(*(p)))
fd_set master_set_read;
FD_SET(600, master_set_read);
=>master_set_read->fd_bits[(600)/32] |= (1<<(600%32));