在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
);
|