关于select函数使用的fd_set
2015-06-21 10:16
381 查看
最近遇到了fd_set, 虽然早早的听说是将描述符按位存储, 但不清楚其实现, 今天就来仔细的看看其实现
看到这里, 就可以粗略的设想一下fd_set应该是long型数组,但根据我们已知, 其是按位存储的, 那我们可能设想到的是c++ 中STL的deque, 当然差别不小...
好了接下去看看.
原来fd_set就是这样!是一个默认大小不可变的数组, 0-31位(即long数组第一个元素)存储大小小于32的描述符,第二位则可存储32-63,共可以存1024个fd
继续看操作:
先看__FD_SET,首先__FD_ELT是将要加入的fd与__NFDBITS直接相除,所得的是这个fd要存储在long数组的哪个元素中
__FD_MASK(d)则是在与__NFDBITS求余后将long类型的1左移,这样一来就得到了这个新fd在某个long数组元素中占的是哪一位了!
最后进行或运算, 这样就能将该fd对应的位置1,存储成功!
了解了__FD_SET, 那么其他两个就不难理解了
/* The fd_set member is required to be an array of longs. */ //从注释可以看出的是, fd_set本质是一串long int类型的数组 typedef long int __fd_mask; /* Some versions of <linux/posix_types.h> define this macros. */ #undef __NFDBITS /* It's easier to assume 8-bit bytes than to get CHAR_BIT. */ #define __NFDBITS (8 * (int) sizeof (__fd_mask)) //32, __fd_mask是long int, 占4字节, 共32位 //下两个宏是用在运算过程中的,先放着 #define __FD_ELT(d) ((d) / __NFDBITS) #define __FD_MASK(d) ((__fd_mask) 1 << ((d) % __NFDBITS))
看到这里, 就可以粗略的设想一下fd_set应该是long型数组,但根据我们已知, 其是按位存储的, 那我们可能设想到的是c++ 中STL的deque, 当然差别不小...
好了接下去看看.
/* fd_set for select and pselect. */ typedef struct { /* XPG4.2 requires this member name. Otherwise avoid the name from the global namespace. */ #ifdef __USE_XOPEN __fd_mask fds_bits[__FD_SETSIZE / __NFDBITS]; // __FD_SETSIZE=1024 __NFDBITS=32,默认__FD_SETSIZE为1024, 那fds_bits默认就是长度为32的long数组 # define __FDS_BITS(set) ((set)->fds_bits) #else __fd_mask __fds_bits[__FD_SETSIZE / __NFDBITS]; # define __FDS_BITS(set) ((set)->__fds_bits) #endif } fd_set;
原来fd_set就是这样!是一个默认大小不可变的数组, 0-31位(即long数组第一个元素)存储大小小于32的描述符,第二位则可存储32-63,共可以存1024个fd
继续看操作:
#define __FD_SET(d, set) \ ((void)(__FDS_BITS(set)[__FD_ELT(d)] |= __FD_MASK(d))) #define __FD_CLR(d, set) \ ((void)(__FDS_BITS(set)[__FD_ELT(d)] &= ~__FD_MASK(d))) #define __FD_ISSET(d, set) \ ((__FDS_BITS(set)[__FD_ELT(d)] & __FD_MASK(d)) != 0)
先看__FD_SET,首先__FD_ELT是将要加入的fd与__NFDBITS直接相除,所得的是这个fd要存储在long数组的哪个元素中
__FD_MASK(d)则是在与__NFDBITS求余后将long类型的1左移,这样一来就得到了这个新fd在某个long数组元素中占的是哪一位了!
最后进行或运算, 这样就能将该fd对应的位置1,存储成功!
了解了__FD_SET, 那么其他两个就不难理解了
相关文章推荐
- swift protocol mutating
- Android数据库SQLite使用详解二 : 学生管理系统的简单实现
- linq分页扩展
- 读后感
- 重踏学习Java路上_Day06(java 基础下与面向对象,二维数组与面向对象基础)
- Git短命令(alias,别名)
- (第五章)java面向对象之this的作用总结
- PATBasic——1009. 说反话 (20)
- Nginx安装部署
- 社説 20150621 新国立競技場 立ち止まって計画を見直そう
- 社説 20150621 農地集積バンク 利用促進の努力が足りない
- FPGA 处理 视频信号噪声
- 关于ftp中文本模式和二进制模式上传文件的区别
- NSNotificationCenter 的使用详解
- hadoop学习(7)----将Hadoop2.6源码导入到win7下的eclipse
- Andrew NG机器学习课程笔记(十一)
- 【最短路】【水题】【cogs 497】奶牛派对
- C++构造函数中抛出的异常
- [数据结构]八皇后(暴力,解答树,DFS回溯)
- Android基础-实现有道词典实例