ZBLOG

讲解一下FD_SET和FD_ZERO函数

FD_SET 和 FD_ZERO 函数详解

在 Linux/Unix 网络编程中,select() 是一种 I/O 多路复用机制,用于监控多个文件描述符(fd)的可读、可写或异常状态。fd_set 是一个位图结构,用于存储需要监控的文件描述符集合。FD_SETFD_ZERO 是操作 fd_set 的宏(macro),它们的作用如下:


1. FD_ZERO(fd_set *set)

作用:清空 fd_set,将所有 fd 位初始化为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)
  • 逻辑:遍历整个 fd_set(通常由多个 long int 组成),并将每个元素置为0。
  • 示例
fd_set readfds;
FD_ZERO(&readfds); // readfds = {0, 0, ..., 0}

2. FD_SET(int fd, fd_set *set)

作用:将指定的文件描述符 fd 添加到 fd_set

底层实现

#define FD_SET(fd, set) \
    ((void)(__FDS_BITS(set)[__FD_ELT(fd)] |= __FD_MASK(fd)))
  • 逻辑分解

    1. 计算索引位置
      • __FD_ELT(fd):确定该 fd 属于哪个数组元素(如 long[16])。
      • ”`c #define __FD_ELT(d) ((d) / __NFDBITS) // e.g., fd=65 → idx=1 (64 bits per long)
      ”`
    2. 设置对应比特位
      • ”`c #define FD_MASK(d) ((fd_mask)(1UL << ((d) % __NFDBITS))) // e.g., fd=65 → bitmask=1<
      ”`
    3. 执行按位或运算
      • ”`c fds_bits[idx] |= mask;
      ”`
  • 示例

int sock_fd = socket(...);
fd_set readfds;
FD_ZERO(&readfds);
FD_SET(sock_fd, &readfds); // Set the bit for sock_fd in readfds.

3. select() + FD_ISSET()

在使用时,通常会配合以下步骤:

// Step1: Initialize fd_set and add fds to monitor.
fd_set readfds;
FD_ZERO(&readfds);
for (int i = start_fd; i < max_fd; i++) {
    FD_SET(i, &readfds);
}

// Step2: Call select() to wait for events.
int ret = select(max_fd + 1, &readfds, NULL, NULL, timeout);

// Step3: Check which fds are ready using FD_ISSET().
if (ret > 0) {
    if (FD_ISSET(sock_fd, &readfds)) {
        printf("sock_fd is readable!\n");
    }
}

4. FAQ(常见问题)

(1) select()为什么限制1024个文件描述符?

  • Linux内核默认定义:
#define FD_SETSIZE     1024 // Max number of file descriptors supported by select()
  • Bitmap存储方式决定了它的上限。

(2) epoll比select有什么优势?

Feature select epoll
Max FDs ~1024 Unlimited
Performance O(n), scans all FDs O(1), event-driven
Scalability Poor for high concurrency Optimized

(3) Windows上的WSAEventSelect是否类似?

Windows的IOCP更接近epoll模型,而WSAEventSelect类似于select但有不同API设计。


5. Summary(总结)

  • FD_ZERO(): Clears all bits in an fd_set.
  • FD_SET(): Sets a specific bit corresponding to a file descriptor.
  • ⚠️ Avoid using select() for high-concurrency scenarios (>1000 connections).
  • 🔥 Modern alternatives: Use epoll/kqueue on Linux/BSD.

如果想深入学习高性能网络编程,可以参考零声教育的《C++后端开发》课程大纲:https://www.0voice.com


内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://sdn.0voice.com/?id=8267

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?