linux的I/O多路轉接select的fd_set數據結構和相應FD_宏的實現分析

在linux實現中,首先爲長整形聲明別名__fd_masklinux

1
typedef long  int    __fd_mask;

定義系統長整形的位數__NFDBITSweb

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

定義fd_set結構能包含的描述符的最大個數__FD_SETSIZE
數組

1
#define __FD_SETSIZE  1024

而後就能夠定義fd_set結構了spa

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個描述符了。code

__FDS_BITS的定義是爲了便於直接引用該結構中的fds_bits,而不用關心內部具體的定義。
ip


關於FD_宏的定義
ci

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宏的定義it

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

__FDS_BITS(set)引用告終構set內部的的相應的數組名,如((set) -> fds_bits)io

而其中的__FD_ELT的定義table

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 );
相關文章
相關標籤/搜索