linux的I/O多路转接select的fd_set数据结构和相应FD_宏的实现分析

http://my.oschina.net/u/870054/blog/212063


在linux实现中,首先为长整形声明别名__fd_mask

1
typedef long   int     __fd_mask;

定义系统长整形的位数__NFDBITS

1
#define __NFDBITS (  8   *(   int   )sizeof(__fd_mask))

定义fd_set结构能包含的描述符的最大个数__FD_SETSIZE

1
#define __FD_SETSIZE   1024

然后就可以定义fd_set结构了

1
2
3
4
5
6
7
8
9
10
typedef struct
          {
#ifdef __USE_XOPEN
    __fd_mask fds_bits[__FD_SETSIZE / __NFDBITS];
#define __FDS_BITS(  set  ) ((s  et  )->fds_bits)
#      else
          __fd_mask __fds_bits[__FD_SETSIZE / __NFDBITS];
#define __FDS_BITS(  set  ) ((  set  )->__fds_bits)
#endif
          } fd_set ;

由数组fds_bits[__FD_SETSIZE / __NFDBITS]的定义可以看出,它将数组fds_bits的长度从通常的__FD_SETSIZE缩短到了(__FD_SETSIZE / __NFDBITS),数组的元素的每个位表示一个描述符,那么一个元素就可以表示__NFDBITS个描述符,整个数组就可以表示(__FD_SETSIZE / __NFDBITS)* __NFDBITS = __FD_SETSIZE个描述符了。

__FDS_BITS的定义是为了便于直接引用该结构中的fds_bits,而不用关心内部具体的定义。


关于FD_宏的定义

1
2
3
4
#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)

对于__FD_SET宏的定义

1
2
#define __FD_SET(d,  set  ) \
          ((  void  ) (__FDS_BITS(  set  )[__FD_ELT(d)] |= __FD_MASK(d)))

__FDS_BITS(set)引用了结构set内部的的相应的数组名,如((set) -> fds_bits)

而其中的__FD_ELT的定义

1
#define __FD_ELT(d)  ((d) / __NFDBITS )

表示描述符d应该包含在数组fds_bits的第几个元素内;

__FD_MASK宏的定义

1
#define __FD_MASK(d) ((__fd_mask)  1   << ((d) % __NFDBITS))

表示描述符d在数组相应元素的第几位;

  

这样看来,在宏__FD_SET中,__FDS_BITS(set)[__FD_ELT(d)] |= __FD_MASK(d) 就把描述符d在结构set的内部数组fd_mask的相应的元素的相应位进行了设置。


对于其他的宏的具体定义如下,分析同上

1
2
3
4
5
6
7
8
9
10
11
#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  )
 
#define __FD_ZERO(  set  ) \
          do   {
              unsigned   int        __i;
              fd_set * __arr = (  set  );
              for   ( __i =   0  ; __i < sizeof(fd_set) / sizeof (__fd_mask); ++__i)
                  __FDS_BITS (__arr)[__i] =   0      ;
            while   (  0  );
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值