select 的 fd_set 问题

我看了下 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.

我的理解对么?

阅读 3.1k
2 个回答

from POSIX:

File descriptor

3.166 File Descriptor
A per-process unique, non-negative integer used to identify an open file for the purpose of file access. The value of a newly-created file descriptor is from zero to {OPEN_MAX}-1. A file descriptor can have a value greater than or equal to {OPEN_MAX} if the value of {OPEN_MAX} has decreased (see sysconf) since the file descriptor was opened. File descriptors may also be used to implement message catalog descriptors and directory streams; see also Open File Description.

当有 1024 的最大单进程 open fd 数量限制的时候,fd 的值是 0 ~ 1023。


fd 就是一个 index 。Linux 一般进程最大 fd 数量是 1024 ,于是进程里会有一个 1024 的数组,记录每一个 fd 的信息。fd 实际就是数组的下标。于是 fd 的值不会超过可用 fd 大小。

也就是说 select 的缺点中,可用套接字数目不大于 1024 这种说法是不准确的,应该也要限制套接字本身的数值大小不能超过 1024.

对于给出的代码,fd本身的数值大小是不能超过1024的。详情请参考:man select中的BUGS章节。

  • image.png
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题