我看了下 fd_set 的源码 https://github.com/openbsd/sr...,如下,
#define FD_SETSIZE 1024
#define __NBBY 8 /* number of bits in a byte */
typedef uint32_t __fd_mask;
#define __NFDBITS ((unsigned)(sizeof(__fd_mask) * __NBBY)) /* bits per mask */
#define __howmany(x, y) (((x) + ((y) - 1)) / (y))
typedef struct fd_set {
__fd_mask fds_bits[__howmany(FD_SETSIZE, __NFDBITS)]; // 相当于 uint32_t fds_bits[32]
} fd_set;
static __inline void
__fd_set(int fd, fd_set *p)
{
p->fds_bits[fd / __NFDBITS] |= (1U << (fd % __NFDBITS));
}
#define FD_SET(n, p) __fd_set((n), (p))
假如现在要加入的套接字是 78,那么 FD_SET 的操作其实就是把 fds_bits 数组的第 78 位置为 1 而已。
如果要加入一个套接字为 7788 的,是不是就没啥用了。
也就是说 select 的缺点中,可用套接字数目不大于 1024 这种说法是不准确的,应该也要限制套接字本身的数值大小不能超过 1024.
我的理解对么?
from POSIX:
File descriptor
当有 1024 的最大单进程 open fd 数量限制的时候,fd 的值是 0 ~ 1023。
fd 就是一个 index 。Linux 一般进程最大 fd 数量是 1024 ,于是进程里会有一个 1024 的数组,记录每一个 fd 的信息。fd 实际就是数组的下标。于是 fd 的值不会超过可用 fd 大小。