今天遇到了在select()前后fd_set的变化问题,查了好久终于找到一个有用的帖子了,很赞,很详细!!原文链接如下:

select用法&原理详解(源码剖析)

我的问题是:

如下图示:在select()函数前后分别打印fdsread和fdsreaduse两个fd_set,

在gjm06-1和gjm06-2之所以一样是因为在打印前我令 fdsreaduse = fdsread; ,然后打印后,执行 selet(maxfd,&fdsreaduse,NULL,NULL,NULL); ,再分别打印两个fd_set。

我的疑惑是:前后两次fdsread都是一样的,为什么fdsreaduse打印出来就不是一样的了。

通过查看代码,发现了两次打印中间只有一个select()函数对fdsreaduse进行了操作。于是上网搜索,才明白select模型(见下摘录)。

【注】

sockfd = 4

remotefd = 5

devfd = 6(devicefd)

我将我所需要的部分,摘录如下:

简单理解select模型

理解select模型的关键在于理解fd_set,为说明方便,取fd_set长度为1字节,fd_set中的每一bit可以对应一个文件描述符fd。则1字节长的fd_set最大可以对应8个fd。

(1)执行fd_set set; FD_ZERO(&set);则set用位表示是0000,0000。

(2)若fd=5,执行FD_SET(fd,&set);后set变为0001,0000(第5位置为1)

(3)若再加入fd=2,fd=1,则set变为0001,0011

(4)执行select(6,&set,0,0,0)阻塞等待

(5)若fd=1,fd=2上都发生可读事件,则select返回,此时set变为0000,0011。注意:没有事件发生的fd=5被清空。

所以,我们可以得到select模型的特点:
(1) 文件描述符个数有限,一般来说这个数目和系统内存关系很大。select使用位域的方式来传递关心的文件描述符,位域就有最大长度。select使用位域的方式传回就绪的文件描述符,调用者需要循环遍历每一个位判断是否就绪,当文件描述符个数很多,但是空闲的文件描述符大大多于就绪的文件描述符的时候,效率很低。

(2) 将fd加入select监控集的同时,还要再使用一个数据结构array保存放到select监控集中的fd,一是用于再select 返回后,array作为源数据和fd_set进行FD_ISSET判断。二是select返回后会把以前加入的但并无事件发生的fd清空,则每次开始 select前都要重新从array取得fd逐一加入(FD_ZERO最先),扫描array的同时取得fd最大值maxfd,用于select的第一个 参数。

(3) 可见select模型必须在select前循环array(加fd,取maxfd),select返回后循环array(FD_ISSET判断是否有时间发生)。

通过以上第(5)条性质,可知:在select()时,只对devfd=6进行了write/read,故remotefd和socket都被清空了。

至此我的问题已解决。

-----------------------------------------------------------------分  割  线--------------------------------------------------------------------

此外,还有一个经典的select原理图,放在这里以便大家理解:

注:select 原理图,摘自 IBM iSeries 信息中心

既然到这里了,就看一下select函数的原型吧

select函数原型:

int select(int maxfdp,fd_set *readfds,fd_set *writefds,fd_set *errorfds,struct timeval *timeout);

/*参数列表
int maxfdp是一个整数值,是指集合中所有文件描述符的范围,即所有文件描述符的最大值加1,不能错!在Windows中这个参数的值无所谓,可以设置不正确。
  
fd_set *readfds是指向fd_set结构的指针,这个集合中应该包括文件描述符,我们是要监视这些文件描述符的读变化的,即我们关心是否可以从这些文件中读取数据了,
如果这个集合中有一个文件可读,select就会返回一个大于0的值,表示有文件可读,如果没有可读的文件,则根据timeout参数再判断是否超时,若超出timeout的时间,
select返回0,若发生错误返回负值。可以传入NULL值,表示不关心任何文件的读变化。
  
fd_set *writefds是指向fd_set结构的指针,这个集合中应该包括文件描述符,我们是要监视这些文件描述符的写变化的,即我们关心是否可以向这些文件中写入数据了,
如果这个集合中有一个文件可写,select就会返回一个大于0的值,表示有文件可写,如果没有可写的文件,则根据timeout参数再判断是否超时,若超出timeout的时间,
select返回0,若发生错误返回负值。可以传入NULL值,表示不关心任何文件的写变化。
  
fd_set *errorfds同上面两个参数的意图,用来监视文件错误异常。
  
struct timeval* timeout是select的超时时间,这个参数至关重要,它可以使select处于三种状态:
第一,若将NULL以形参传入,即不传入时间结构,就是将select置于阻塞状态,一定等到监视文件描述符集合中某个文件描述符发生变化为止;
第二,若将时间值设为0秒0毫秒,就变成一个纯粹的非阻塞函数,不管文件描述符是否有变化,都立刻返回继续执行,文件无变化返回0,有变化返回一个正值;
第三,timeout的值大于0,这就是等待的超时时间,即 select在timeout时间内阻塞,超时时间之内有事件到来就返回了,否则在超时后不管怎样一定返回,返回值同上述。
*/

头文件:

select位于: #include <sys/select.h>

struct timeval位于: #include <sys/time.h>

返回值:

负值:select错误
正值:某些文件可读写或出错
0:等待超时,没有可读写或错误的文件

参数timeout为结构timeval,用来设置select()的等待时间,其结构定义如下:

struct timeval
{
time_t tv_sec;//second
time_t tv_usec;//minisecond
};

over。。。

参考:

本人墙推: Linux中select IO复用机制&使用代码实例

select处理带外数据&解决socket中多用户问题代码

select用法&原理详解(源码剖析)(转)的更多相关文章

  1. Java开源生鲜电商平台-盈利模式详解(源码可下载)

    Java开源生鲜电商平台-盈利模式详解(源码可下载) 该平台提供一个联合买家与卖家的一个平台.(类似淘宝购物,这里指的是食材的购买.) 平台有以下的盈利模式:(类似的平台有美菜网,食材网等) 1. 订 ...

  2. ArrayList详解-源码分析

    ArrayList详解-源码分析 1. 概述 在平时的开发中,用到最多的集合应该就是ArrayList了,本篇文章将结合源代码来学习ArrayList. ArrayList是基于数组实现的集合列表 支 ...

  3. LinkedList详解-源码分析

    LinkedList详解-源码分析 LinkedList是List接口的第二个具体的实现类,第一个是ArrayList,前面一篇文章已经总结过了,下面我们来结合源码,学习LinkedList. 基于双 ...

  4. Shiro的Filter机制详解---源码分析

    Shiro的Filter机制详解 首先从spring-shiro.xml的filter配置说起,先回答两个问题: 1, 为什么相同url规则,后面定义的会覆盖前面定义的(执行的时候只执行最后一个). ...

  5. udhcp详解源码(序)

    最近负责接入模块,包括dhcp.ipoe和pppoe等等.所以需要对dhcp和ppp这几个app的源代码进行一些分析.网上有比较好的文章,参考并补充自己的分析. 这篇udhcp详解是基于busybox ...

  6. Shiro的Filter机制详解---源码分析(转)

    Shiro的Filter机制详解 首先从spring-shiro.xml的filter配置说起,先回答两个问题: 1, 为什么相同url规则,后面定义的会覆盖前面定义的(执行的时候只执行最后一个). ...

  7. Android4.3 屏蔽HOME按键返回桌面详解(源码环境下)

    点击打开链接 首先声明我是做系统开发的(高通平台),所以下面介绍的方法并不适合应用开发者. 最经有个需求要屏蔽HOME按键返回桌面并且实现自己的功能,发现以前的方式报错用不了,上网搜索了一下,发现都是 ...

  8. Python-Flask框架之——图书管理系统 , 附详解源码和效果图 !

    该图书管理系统要实现的功能: 1. 可以通过添加窗口添加书籍或作者, 如果要添加的作者和书籍已存在于书架上, 则给出相应的提示. 2. 如果要添加的作者存在, 而要添加的书籍书架上没有, 则将该书籍添 ...

  9. SpringBoot原理深入及源码剖析(一) 依赖管理及自动配置

    前言 传统的Spring框架实现一个Web服务需要导入各种依赖jar包,然后编写对应的XML配置文件等,相较而言,SpringBoot显得更加方便.快捷和高效.那么,SpringBoot究竟是如何做到 ...

随机推荐

  1. [Cerc2005]Knights of the Round Table

    题目描述 有n个骑士经常举行圆桌会议,商讨大事.每次圆桌会议至少有3个骑士参加,且相互憎恨的骑士不能坐在圆桌的相邻位置.如果发生意见分歧,则需要举手表决,因此参加会议的骑士数目必须是大于1的奇数,以防 ...

  2. 入门OJ:八中生成树2

    题目描述 八中里面有N个建设物,M条边.对于这种要建最小生成树的问题,你应该很熟练了.现在老大决定降低某条边的费用,然后这条边必须要被选中,因为这条路他每天都要走,自然......问选了这条边后是否可 ...

  3. EL&Filter&Listener:EL表达式和JSTL,Servlet规范中的过滤器,Servlet规范中的监听器,观察着设计模式,监听器的使用,综合案例学生管理系统

    EL&Filter&Listener-授课 1 EL表达式和JSTL 1.1 EL表达式 1.1.1 EL表达式介绍 *** EL(Expression Language):表达式语言 ...

  4. 运用 pyinstaller 打包的python exe文件运行 去掉命令行窗口及其他参数汇总

    运行exe文件的时候,会弹出一个dos命令窗口,这个窗口可以看到一些打印信息,如果想只运行tkinter 页面,去掉dos窗口需要在打包的时候 加上 -w 参数 pyinstaller -F XX.p ...

  5. Typora+PicGo+Gitee打造图床

    前言 ​ 自己一直使用的是Typora来写博客,但比较麻烦的是图片粘贴上去后都是存储到了本地,写好了之后放到博客园等地,图片不能直接访问,但如今Typora已经支持图片上传,所以搞了一波图片上传到Gi ...

  6. Less中Css预处理器

    Less.js 安装 npm install -g less 变量 basic 变量采用@进行变量定义.变量可以直接参加运算. @width:100px; .variables{ width:@wid ...

  7. SQL性能优化汇总

    SQL效率低下也是导致性能差的一个非常重要的原因,可以通过查看执行计划看SQL慢在哪里,一般情况,SQL效率低下原因主要有:   类别 子类 表达式或描述 原因 索引 未建索引 无 产生全表扫描 未利 ...

  8. jQuery 真伪数组的转换

    //真数组转换伪数组 var arr = [1,3,5,7,9]; var obj = {}; [].push.apply(obj,arr); console.log(obj) //伪数组转真数组 v ...

  9. Angular入门到精通系列教程(14)- Angular 编译打包 & Docker发布

    目录 1. 概要 2. 编译打包 2.1. 基本打包命令 2.2. 打包部署到二级目录 3. Angular站点的发布 3.1. web服务器发布 3.2. 使用docker发布 4. 总结 环境: ...

  10. jemeter断言和性能分析

    一.添加断言 1.原因:检查是否有该结果,一般一个请求过去除了400和500的只要通过的都会代表请求成功,比如登录页面及时填写了错误密码,虽然会返回密码错误,但这个请求还是成功的,所以我们要添加断言, ...