曲径通幽论坛

标题: 关于 select() 函数中的 fd_set 类型说明 [打印本页]

作者: beyes    时间: 2009-8-23 11:13
标题: 关于 select() 函数中的 fd_set 类型说明
在 include/linux/type.h 中看到:
#define typedef __kernel_fd_set    fd_set

在 include/linux/posix_types.h 中看到:
typedef struct {
           unsigned long fds_bits[__FDSET_LONGS]
} __kernel_fd_set;

同样在 include/linux/posix_types.h 中看到:
#define   __FDSET_LONGS  (__FD_SET_SIZE / __NFDBITS)

而在 include/sys/selsect.h 中可以看到:
#define   FD_SETSIZE     __FD_SETSIZE   1024

在 include/linux/posix_types.h 中或在 include/bits/typesize.h 中看到:
#define     __FD_SETSIZE   1024

在 include/linux/posix_types.h 中看到:
#define __NFDBITS       (8 * sizeof(unsigned long))

综合上面,展开 __FDSET_LONGS 宏
#define   __FDSET_LONGS    (1024 / 8 * sizeof(unsigned long))
上面,unsigned long 在不同的平台上的位宽会不同,如在 32 位平台上,位宽为 4 字节的 32 位数,所以要弄成 8 * sizeof(unsigned long) 形式,因为在别的平台上 unsigned long 是不同的,但一个字节永远都是固定为 8 位。
对于 FD_SETSIZE ,32 位进程的默认值是 1024,但是,通过包含系统提供的任何头文件之前也可以为其定义较大的数值,在编译时可以增加该值。在 64 位的系统上,默认值为 65536。

之所以像上面这样定义,正是为了可移植性考虑。像这样用宏经过层层套装起来的定义,是一种对用户不透明的数据类型。现在,我们可以认为,fs_set 是位的数组(实际上,这个数组有 32 个 unsigned long 型数据),总共的位数是(在 32 位平台上):8 * 4 * 32  = 1024 。其中每 1 位对应于每个文件描述符,如下所示:
fd0:0
fd1:1
fd2:0
... ...
上面,每一位要么是 0 ,要么是 1。是 0 ,则表示对该文件描述符不敢兴趣,而 1 意味着对其感兴趣。对操作 fd_set 操作的唯一方法是用相应的宏。

关于 select() 函数应用见:http://www.groad.net/bbs/read.php?tid-1064.html




欢迎光临 曲径通幽论坛 (http://www.groad.net/bbs/) Powered by Discuz! X3.2