fd_set是一個結構
/* The fd_set member is required to be an array of longs. */ typedef long int __fd_mask; /* Some versions of <linux/posix_types.h> define this macros. */ #undef __NFDBITS /* It's easier to assume 8-bit bytes than to get CHAR_BIT. */ #define __NFDBITS (8 * (int) sizeof (__fd_mask)) //32 #define __FD_ELT(d) ((d) / __NFDBITS) #define __FD_MASK(d) ((__fd_mask) 1 << ((d) % __NFDBITS)) /* fd_set for select and pselect. */ 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];// __FD_SETSIZE=1024 __NFDBITS=32 # 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;
可以看到結構裡面有一個fds_bits,大小是32(1024/32)。
__fd_mask是一個長整形,佔4位位元組,也就是4*8=32bit,每一個bit都對應一個fd。也就是很多人說的,第一位對應0-31,第二位對應32-63.
#define __FD_SET(d, set) \ ((void) (__FDS_BITS (set)[__FD_ELT (d)] |= __FD_MASK (d))) #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)
FD_SET函式,分開看__FDS_BITS (set)結構裡面的fds_bits陣列。__FD_ETL(d),除32,看這個fd在fd_bits第幾位上。
FD_MASK 這個巨集特別的牛逼,確實佩服一下,先模32,然後就得出餘數,然後將1向左移位,這樣一來就可以進行&,互不影響。