select()机制中提供一种fd_set的数据结构,它实际上是long类型的数组每一个数组元素都能与一打开的文件句柄(不管是socket句柄,还是其他文件或命名管道或设备句柄)建立联系,建立联系的工作由程序员完成,当调用select()时,由内核根据IO状态修改fd_set的内容,由此来通知执行了select()的进程哪一socket或文件发生了可读或可写事件

fd_set结构体原型:

typedef struct
{
/*XPG4.2requiresthismembername.Otherwiseavoidthename
fromtheglobalnamespace.*/
#ifdef__USE_XOPEN
__fd_maskfds_bits[__FD_SETSIZE/__NFDBITS];
#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;

系统提供了4个宏对描述符集进行操作:

#include <sys/select.h>
#include <sys/time.h>
void FD_SET(int fd, fd_set *fdset);
void FD_CLR(int fd, fd_set *fdset);
void FD_ISSET(int fd, fd_set *fdset);
void FD_ZERO(fd_set *fdset);

宏FD_SET设置文件描述符集fdset中对应于文件描述符fd的位(设置为1),宏FD_CLR清除文件描述符集fdset中对应于文件描述符fd的位(设置为0),宏FD_ZERO清除文件描述符集fdset中的所有位(既把所有位都设置为0)。使用这3个宏在调用select前设置描述符屏蔽位,在调用select后使用FD_ISSET来检测文件描述符集fdset中对应于文件描述符fd的位是否被设置。

常见用法:

fd_set fdset;
FD_ZERO(&fdset); /*将set清零使集合中不含任何fd,清空fdset与所有文件句柄的联系*/
FD_SET(fd, &fdset); /*将fd加入set集合,建立文件句柄fd与fdset的联系*/
FD_CLR(fd, &fdset); /*将fd从set集合中清除,清除文件句柄fd与fdset的联系*/
FD_ISSET(fd, &fdset); /*在调用select()函数后,用FD_ISSET来检测fd是否在set集合中,当检测到fd在set中则返回真,否则,返回假(0)*/
以上式子中的fd为socket句柄。

示例:

#include <stdio.h>
#include <sys/select.h>
#include <unistd.h>
int main(int argc, char **argv){    fd_set fdset;    FD_ZERO (&fdset);                          /*清空集合中所有的元素*/    FD_SET(STDOUT_FILENO,&fdset);              /*设置stdout,使集合中包含stdout*/  if(FD_ISSET(STDOUT_FILENO,&fdset)!=0)      /*测试stdout是否包含在集合中*/        printf("stdout has been set\n");    else        printf("stdout has not been set\n");   FD_CLR(STDOUT_FILENO,&fdset);              /*从位向量中清除stdout*/  if(FD_ISSET(STDOUT_FILENO,&fdset)!=0)      /*再次测试*/       printf("stdout has been set\n");    else        printf("stdout has not been set\n");FD_ZERO(&fdset);FD_SET(1, &fdset);FD_SET(2, &fdset);FD_SET(3, &fdset);FD_SET(7, &fdset);printf("fdset.__fds_bits[0] = %d\n", fdset.__fds_bits[0]);return 0;
}

运行结果:

stdout has been set
stdout has not been set
fdset.__fds_bits[0] = 142

即:将fdset所有元素的二进制连接为一个整体,FD_SET(1, &fdset)、FD_SET(2, &fdset)、FD_SET(3, &fdset)、FD_SET(7, &fdset)相当于将二进制中的bit1、bit2、bit3、bit7设置为1,即1000 1110,所以fdset.__fds_bits[0]值为142。

可以查看fdset的定义,是一个long类型数组,数组大小为__FD_SETSIZE/__NFDBITS,前者为1024,后者与系统有关,这种定义保证了fdset数组最大可以存储__FD_SETSIZE个bit位。

一句话:fd_set就是一个long类型数组,数组中所有元素按照二进制位排列,每一位都对应一个文件描述符(通过索引关联)。

通常,操作系统通过宏FD_SETSIZE来声明在一个进程中select所能操作的文件描述符的最大数目。例如:
在4.4BSD的头文件中我们可以看到:

#ifndef FD_SETSIZE
#define FD_SETSIZE 1024
#endif

在红帽Linux的头文件<bits/types.h>中我们可以看到:

#define __FD_SETSIZE 1024

以及在头文件<sys/select.h>中我们可以看到:

#include <bits/types.h>
#define FD_SETSIZE __FD_SETSIZE

既定义FD_SETSIZE为1024,一个整数占4个字节,既32位,那么就是用包含32个元素的整数数组来表示文件描述符集。我们可以在头文件中修改这个值来改变select使用的文件描述符集的大小,但是必须重新编译内核才能使修改后的值有效。当前版本的unix操作系统没有限制FD_SETSIZE的最大值,通常只受内存以及系统管理上的限制。

27、fd_set与FD_SETSIZE详解相关推荐

  1. python装饰器setter_第7.27节 Python案例详解: @property装饰器定义属性访问方法getter、setter、deleter...

    上节详细介绍了利用@property装饰器定义属性的语法,本节通过具体案例来进一步说明. 一.    案例说明 本节的案例是定义Rectangle(长方形)类,为了说明问题,除构造函数外,其他方法都只 ...

  2. ext核心API详解

    http://hi.baidu.com/j2me/profile 1 EXT核心API详解(一)-Ext 1 EXT核心API详解(二)-Array/Date/Function/Number/Stri ...

  3. 孙鑫 java web_javaweb(code) 孙鑫老师的java web 开发详解的源代码 - 下载 - 搜珍网

    javaweb开发详解(code)/AppendixA/FirstPage.html javaweb开发详解(code)/AppendixA/form.html javaweb开发详解(code)/A ...

  4. 御剑情缘服务器维护,御剑情缘7月27日更新维护内容及活动详解介绍

    导 读 御剑情缘7月27日更新维护了什么内容?御剑情缘目前在7月27日为玩家们进行了游戏更新,不少小伙伴们还不清楚有哪些玩法吧!下面是御剑情缘7月27日更新维护内容及活动详解介绍,一起来看下吧! ▲燕 ...

  5. 2010 27寸 imac 升级固态_2017 款 iMac,27 寸升级换 SSD 固态硬盘拆机详解

    想要 iMac玩游戏?怎么能带动?如何解决卡顿问题?别急,给您带来2017 款 iMac,27 寸升级换 SSD 固态硬盘拆机详解,拆机并不复杂,动手能力差的同学看了这篇文章会觉得原来我也可以,那让我 ...

  6. unity技美27——优化项目内美术3D,2D等资源,详解unity打包体的潜规则与案例

    很多朋友美术朋友在面试中经常会被问到一类问题,就是怎么优化你的美术资源. 当我们不熟练使用unity,以级不懂得unity的潜规则时,美术能做到的仅仅是: 1优化模型面数.或者用次世代的方式制作法线贴 ...

  7. 详解即将于Go 1.18加入的Go泛型特性 | Gopher Daily (2021.09.27) ʕ◔ϖ◔ʔ

    每日一谚:use errors.Is(err, pkg.ErrFoo) rather than err == pkg.ErrFoo. Go技术生态 详解即将于Go 1.18加入的Go泛型特性 - ht ...

  8. 3.2-7 字体属性详解

    字体属性详解 1.font-family属性 1.font-family属性用于设置字体: font-family:"微软雅黑": 2.字体可以是列表形式,一般英语字体放在前面,后 ...

  9. 【epoll】epoll使用详解(精髓)--研读和修正

    目录 epoll 和select epoll的接口 如何来使用epoll epoll程序框架 伪代码: 示例代码 大致流程 实例源码 相关知识 Socket的阻塞模式和非阻塞模式 如何动态的改变lis ...

最新文章

  1. 苹果连接电脑只能充电_苹果获得MagSafe式充电技术专利 可自动连接充电
  2. oracle excel报表开发,深入浅出OracleEBS之Excel报表开发.doc
  3. [IE技巧] 让IE 以全屏模式启动
  4. was中java目录_was8.5选择安装选项,安装应用程序的目录填写自定义目录,应用部署成功后访问不了页面?...
  5. log4j简介及应用
  6. 剑指offer 面试题49. 丑数
  7. Zune支持哪些格式?
  8. java 连续数字_java 如何判断数字是否连续?求大神解答
  9. 五、线性回归和多项式回归实现
  10. 电脑便签、备忘录 可以直接从电脑桌面看到提醒事项的软件推荐
  11. [轻笔记] SHAP值的计算步骤
  12. 云出阿里见月明(一)
  13. 全球重力异常值和磁场异常值提取
  14. You Are the One HDU - 4283 区间DP
  15. Wince Battery driver
  16. 根轨迹法不完全笔记(自动控制原理)
  17. 互联网最后一个绯闻女友出嫁 大众点评联姻腾讯
  18. 怎样建立产品体系?(二)- 战略
  19. 360(drizzleDumper)脱壳教程“某药数据”
  20. 数学建模笔记——插值拟合模型(二)

热门文章

  1. 计算机职称证的用途,计算机软考高项过了有什么用处
  2. 【国产数据库】GBase学习⑤ - gsql 客户端连接工具
  3. Excel如何批量加大列宽
  4. Windows检测是否存在ms17-010(永恒之蓝)_Server Message Block
  5. 实验三 基本IO口扩展实验
  6. Mapbox Style 规范(中文)
  7. CornerStone 破解 最简单的破解方法
  8. 【微服务】GateWay概念与使用
  9. 让HR眼前一亮:30个APP项目软件测试经验,点燃你的简历
  10. Array和Arrays