FD_SET、FD_ISSET和FD_ZERO

select使用涉及四个宏,通过glibc把他们实现找出来说一说:

typedef long int __fd_mask;

 #define __NFDBITS       (8 * (int) sizeof (__fd_mask))//32位,就是32,64位这就是64,后面以32位为例;
#define __FD_ELT(d)     ((d) / __NFDBITS)//对应的fd除以32的商
#define __FD_MASK(d)    ((__fd_mask) 1 << ((d) % __NFDBITS))//将1向左移动fd除以32的余数(假设余数为a)个 位数;即,将第a位置1;

综上,假如fd为5,则__FD_ELT为0;__FD_MASK为5,就是把1左移5位,即第(fd)5位置1(从0开始数);

          假如fd为33,则__FD_ELT为1;__FD_MASK为1,就是把1左移1位,即第(fd)32*1+1位置1;

/* fd_set for select and pselect.  */ fd_set结构体的定义:
typedef struct
  {
    /* XPG4.2 requires this member name.  Otherwise avoid the name
       from the global namespace.  */
#ifdef __USE_XOPEN
    __fd_mask fds_bits[__FD_SETSIZE / __NFDBITS];//包含32个long整型数的数组;
# define __FDS_BITS(set) ((set)->fds_bits)
#else
    __fd_mask __fds_bits[__FD_SETSIZE / __NFDBITS];
# define __FDS_BITS(set) ((set)->__fds_bits)
#endif
  } fd_set;

/* Maximum number of file descriptors in `fd_set'.  */
#define FD_SETSIZE              __FD_SETSIZE //内核中定义的,一般为1024

#ifdef __USE_MISC
/* Sometimes the fd_set member is assumed to have this type.  */
typedef __fd_mask fd_mask;

/* Number of bits per word of `fd_set' (some code assumes this is 32).  */
# define NFDBITS                __NFDBITS
#endif


/* Access macros for `fd_set'.  */
#define FD_SET(fd, fdsetp)      __FD_SET (fd, fdsetp)
#define FD_CLR(fd, fdsetp)      __FD_CLR (fd, fdsetp)
#define FD_ISSET(fd, fdsetp)    __FD_ISSET (fd, fdsetp)
#define FD_ZERO(fdsetp)         __FD_ZERO (fdsetp)
 
 
 #define __FD_SET(d, set) \
  ((void) (__FDS_BITS (set)[__FD_ELT (d)] |= __FD_MASK (d)))

        以下几个类似,就说明这一个,__FD_SET的作用就是用个32位整型数的每一位代表一个需要监控的fd;fd_set结构是一个包含有32个整型数的数组,所以可以加入fd0-1023用于监控;同样接上,说明他的具体实现:

       假如fd为5,则__FD_ELT为0,就表示数组第1个元素(数组下标从0开始);__FD_MASK为5,就是把1左移5位,即把第1个元素第5位置1;

          假如fd为33,则__FD_ELT为1,就表示数组第2个元素;__FD_MASK为1,就是把1左移1位,即把第2个整型数的第1为置1;

         综上,可以理解要监控fd,就是将1024个位的相应fd位置1,只是内核将1024分割为32份用一个整型数表示了;

#define __FD_CLR(d, set) \
  ((void) (__FDS_BITS (set)[__FD_ELT (d)] &= ~__FD_MASK (d)))
#define __FD_ISSET(d, set) \
  ((__FDS_BITS (set)[__FD_ELT (d)] & __FD_MASK (d)) != 0)

猜你喜欢

转载自blog.csdn.net/hzj_001/article/details/81587109
fd