博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
linux的I/O多路转接select的fd_set数据结构和相应FD_宏的实现分析
阅读量:5858 次
发布时间:2019-06-19

本文共 1846 字,大约阅读时间需要 6 分钟。

hot3.png

在linux实现中,首先为长整形声明别名__fd_mask

1
typedef long 
int   
__fd_mask;

定义系统长整形的位数__NFDBITS

1
#define __NFDBITS (
8 
*( 
int 
)sizeof(__fd_mask))

定义fd_set结构能包含的描述符的最大个数__FD_SETSIZE

1
#define __FD_SETSIZE 
1024

然后就可以定义fd_set结构了

1
2
3
4
5
6
7
8
9
10
typedef struct
        
{
#ifdef __USE_XOPEN
    __fd_mask fds_bits[__FD_SETSIZE / __NFDBITS];
#define __FDS_BITS(
set
) ((s
et
)->fds_bits)
#    
else
        
__fd_mask __fds_bits[__FD_SETSIZE / __NFDBITS];
#define __FDS_BITS(
set
) ((
set
)->__fds_bits)
#endif
        
} fd_set ;

由数组fds_bits[__FD_SETSIZE / __NFDBITS]的定义可以看出,它将数组fds_bits的长度从通常的__FD_SETSIZE缩短到了(__FD_SETSIZE / __NFDBITS),数组的元素的每个位表示一个描述符,那么一个元素就可以表示__NFDBITS个描述符,整个数组就可以表示(__FD_SETSIZE / __NFDBITS)* __NFDBITS = __FD_SETSIZE个描述符了。

__FDS_BITS的定义是为了便于直接引用该结构中的fds_bits,而不用关心内部具体的定义。

关于FD_宏的定义

1
2
3
4
#define FD_SET(fd, fdsetp)     __FD_SET(fd,fdsetp)
#define FD_CLR(fd, fdsetp)     __FD_CLR(fd,fdsetp)
#define FD_ISSET(fd, fdsetp)   __FD_ISSET(fd,fdsetp)
#define FD_ZERO(fdsetp)        __FD_ZERO(fdsetp)

对于__FD_SET宏的定义

1
2
#define __FD_SET(d,
set
) \
        
((
void
) (__FDS_BITS(
set
)[__FD_ELT(d)] |= __FD_MASK(d)))

__FDS_BITS(set)引用了结构set内部的的相应的数组名,如((set) -> fds_bits)

而其中的__FD_ELT的定义

1
#define __FD_ELT(d)  ((d) / __NFDBITS )

表示描述符d应该包含在数组fds_bits的第几个元素内;

__FD_MASK宏的定义

1
#define __FD_MASK(d) ((__fd_mask)
1 
<< ((d) % __NFDBITS))

表示描述符d在数组相应元素的第几位;

  

这样看来,在宏__FD_SET中,__FDS_BITS(set)[__FD_ELT(d)] |= __FD_MASK(d) 就把描述符d在结构set的内部数组fd_mask的相应的元素的相应位进行了设置。

对于其他的宏的具体定义如下,分析同上

1
2
3
4
5
6
7
8
9
10
11
#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
)
 
#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
);

转载于:https://my.oschina.net/u/870054/blog/212063

你可能感兴趣的文章
聊聊spring-data-redis的连接池的校验
查看>>
Swoole 源码分析——基础模块之Queue队列
查看>>
Nginx实践篇(4)- Nginx代理服务 - 正向代理和反向代理
查看>>
从0开发豆果美食小程序——项目搭建
查看>>
【译】WebSocket协议第二章——一致性要求(Conformance Requirements)
查看>>
Sublime Text3全局搜索/在文件夹中查找默认排除node_modules目录,Sublime小技巧——吕江民·敬上...
查看>>
Struts 入门 2
查看>>
Java™ 教程(运算符)
查看>>
React Event 实现原理
查看>>
在linux下合并磁盘
查看>>
WEB安全Permeate漏洞靶场挖掘实践
查看>>
JavaScript工作原理(七):Web Workers的构建快和5种使用场景
查看>>
win10+vscode部署java开发环境
查看>>
「报表案例分享」数据上报+分析助力实现精准扶贫
查看>>
vue — 组件间通信
查看>>
ES6学习-Module
查看>>
高性能配置管理中心 duic
查看>>
vue-cli 3.x配置使用vux
查看>>
『总结』web前端开发常用代码整理
查看>>
管理之善,在于让员工有机会试错
查看>>