分析FD_SET背后的实现,用位图保存文件描述符

今天看DTM 的源代码,其中又碰到了我们神奇的select函数,

分析FD_SET背后的实现,用位图保存文件描述符

这个函数总是和以下这些宏定义相关连:

分析FD_SET背后的实现,用位图保存文件描述符

于是我们去看看这些宏的实现吧

//每个ulong为32位,可以表示32个bit。
//fd  >> 5 即 fd / 32,找到对应的ulong下标i;fd & 31 即fd % 32,找到在ulong[i]内部的位置
 
#define __FD_SET(fd, fdsetp)   (((fd_set *)(fdsetp))->fds_bits[(fd) >> 5] |= (1<<((fd) & 31)))             //设置对应的bit
#define __FD_CLR(fd, fdsetp)   (((fd_set *)(fdsetp))->fds_bits[(fd) >> 5] &= ~(1<<((fd) & 31)))            //清除对应的bit
#define __FD_ISSET(fd, fdsetp)   ((((fd_set *)(fdsetp))->fds_bits[(fd) >> 5] & (1<<((fd) & 31))) != 0)     //判断对应的bit是否为1
#define __FD_ZERO(fdsetp)   (memset (fdsetp, 0, sizeof (*(fd_set *)(fdsetp))))                             //memset bitmap

对上面的宏来说,他们操作的一个基础是:fd_set这个数据结构

#define __NFDBITS (8 * sizeof(unsigned long))                //每个ulong型可以表示多少个bit,
#define __FD_SETSIZE 1024                                          //socket最大取值为1024
#define __FDSET_LONGS (__FD_SETSIZE/__NFDBITS)     //bitmap一共有1024个bit,共需要多少个ulong
 
typedef struct {
    unsigned long fds_bits [__FDSET_LONGS];                 //用ulong数组来表示bitmap
} __kernel_fd_set;
 
typedef __kernel_fd_set   fd_set;

如果你需要具象化的记忆:
分析FD_SET背后的实现,用位图保存文件描述符