您的位置:首页 > 其它

关于select函数使用的fd_set

2015-06-21 10:16 381 查看
最近遇到了fd_set, 虽然早早的听说是将描述符按位存储, 但不清楚其实现, 今天就来仔细的看看其实现

/* The fd_set member is required to be an array of longs.  */
//从注释可以看出的是, fd_set本质是一串long int类型的数组

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, __fd_mask是long int, 占4字节, 共32位

//下两个宏是用在运算过程中的,先放着
#define __FD_ELT(d) ((d) / __NFDBITS)
#define __FD_MASK(d)    ((__fd_mask) 1 << ((d) % __NFDBITS))


看到这里, 就可以粗略的设想一下fd_set应该是long型数组,但根据我们已知, 其是按位存储的, 那我们可能设想到的是c++ 中STL的deque, 当然差别不小...

好了接下去看看.

/* 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,默认__FD_SETSIZE为1024, 那fds_bits默认就是长度为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;


原来fd_set就是这样!是一个默认大小不可变的数组, 0-31位(即long数组第一个元素)存储大小小于32的描述符,第二位则可存储32-63,共可以存1024个fd

继续看操作:

#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,首先__FD_ELT是将要加入的fd与__NFDBITS直接相除,所得的是这个fd要存储在long数组的哪个元素中

__FD_MASK(d)则是在与__NFDBITS求余后将long类型的1左移,这样一来就得到了这个新fd在某个long数组元素中占的是哪一位了!

最后进行或运算, 这样就能将该fd对应的位置1,存储成功!

了解了__FD_SET, 那么其他两个就不难理解了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: