linux系统中select函数的用法实现

news2024/12/23 12:55:53

前言:

select机制已经被很多人都讲解过,select使用起来也不是特别难,为什么还要花时间再次讲解select机制?

在回答这个问题之前,我们先问一下自己,是否有足够的信心保证在使用select编程时不出错,select机制虽然看起来简单,实际在使用时有很多坑,当我们没有从原理上真正理解select机制时,我们随时会掉入这些坑,所以这篇文章我尽量把select实现原理和细节交待清楚。

1.select简介

select机制是一种I/O多路复用技术,它可以同时监视多个文件描述符,当某个文件描述符就绪(一般是读写就绪)时,就会通知程序进行相应的操作。

select机制的优点是可以同时处理多个连接,避免了大量的线程或进程切换,提高了系统的并发性能。

在Linux系统中,select机制可以通过select函数来实现。select函数的参数包括需要监视的文件描述符集合、超时时间等。当select函数返回时,程序可以通过遍历文件描述符集合来确定哪些文件描述符已经就绪,然后进行相应的操作。

2.select实现原理

(老规矩先上原理图)

这张原理图把select主要活动轨迹都进行了描述。

  • select核心实现原理是位图,select总共有三种位图,分别为读,写,异常位图,用户程序预先将socket文件描述符注册至读,写,异常位图,然后通过select系统调用轮询位图中的socket的读,写,异常事件。

  • select底层通过轮询方式获取读,写,异常位图中注册的socket文件事件,如果检测到有socket文件处于就绪状态,则会将socket对应的事件设置到输出位图,等所有位图中的socket都被轮询完,会统一将输出位图通过copy_to_user函数复制到输入位图,并且覆盖掉输入位图注册信息(也就是用户初始化的位图被内核修改)

  • select轮询完所有位图,如果未检测到任何socket文件处于就绪状态,根据超时时间确定是否返回或者阻塞进程。

  • socket检测到读,写,异常事件后,会通过注册到socket等待队列的回调函数poll_wake将进程唤醒,唤醒的进程将再次轮询所有位图。

  • select返回时会将剩余的超时时间通过copy_to_user覆盖原来的超时时间。

3.select位图

3.1 select位图定义

#define __FD_SETSIZE        1024

#define __NFDBITS   (8 * (int) sizeof (long int))

typedef struct

{

    long int fds_bits[__FD_SETSIZE / __NFDBITS];

} fd_set;

  • select位图为1024比特位图,通过整型数组模拟而成。

  • select位图每个比特对应一个文件描述符数值。

  • select位图数组长度为16,每个数组元素为8字节,一个字节为8比特,位图大小=16 * 8 * 8 = 1024比特。

3.2 常用位图操作函数:

void FD_CLR(int fd, fd_set *set); //设置fd对应位图位置为0。

int FD_ISSET(int fd, fd_set *set); //判断fd对应位图位置是否为1。

void FD_SET(int fd, fd_set *set); //设置fd对应位图位置为1。

void FD_ZERO(fd_set *set);//整个位图清零。

4.select编程

4.1 select函数原型

int select(int nfds, fd_set *readfds, fd_set *writefds,          

          fd_set *exceptfds, struct timeval *timeout);

功能:select函数是Linux系统中的一种I/O多路复用机制,它可以同时监视多个文件描述符。

参数:

nfds:最大文件描述符+1。

readfds:读文件描述符集合,可设置为NULL。

writefds:写文件描述符集合,可设置为NULL。

exceptfds:异常文件描述符集合,可设置为NULL。

timeout:超时时间,设置为NULL为阻塞模式,

struct timeval {

    __kernel_time_t     tv_sec;     //秒,超时多少秒。

    __kernel_suseconds_t    tv_usec;    //微妙,超时多少微秒。

};

返回值:

成功:返回检测到的文件描述符数量。

失败:返回-1,设置errno。

超时:返回0。

4.2 select使用示例:

fd_set rfds;

FD_ZERO(&rfds_storage); //清空位图

FD_SET(sock_fd, &rfds_storage); //设置位图

struct  timeval tv = {.tv_sec = 5, .tv_usec = 0}; //设置超时时间

ret = select(max_fd + 1, &rfds, NULL, NULL, &tv);

4.3 select编程模型

5.select常见问题?

问题1:select函数最大文件描述(maxfd)有什么作用?

select使用1024比特位图监测最多1024个文件描述符,然而实际的情况很少会到达1024文件描述符上限,使用maxfd可以避免每次都轮询1024个文件描述符,从而提高轮询效率。

maxfd通常设置为已打开最大文件描述符+1,目的是为了保证位图中每个文件描述符都被轮询到。

问题2:select优缺点有哪些?

优点:

  • select支持多种文件描述符类型,包括socket、标准输入输出、管道、FIFO等。

  • select是跨平台的,可以在多种操作系统上使用。

缺点:

  • select的效率不高,每次调用select都需要将所有的文件描述符从用户态复制到内核态,这个过程比较耗时。

  • select返回后需要遍历所有的文件描述符,找到就绪的文件描述符,这个过程也比较耗时。

  • select支持的文件描述符数量有限,通常是1024个。 

问题3:select为什么会有1024文件描述符限制?

  • 进程默认打开最大文件描述符为1024(次要原因)。

  • select采用轮询的方式获取读,写,异常事件,如果需要轮询的文件描述符比较多的话,select执行效率会非常低(个人观点)。

  • select是通过一个整型数组来模拟位图,整型数组长度和元素大小已经固定,只能模拟出1024比特位图,使用select如果超过1024文件描述符的限制,可能会导致内存越界和其他未知问题(真正原因)。

问题4:select有哪些设计缺陷?

  • select最大文件描述符为1024,所以无法满足高并发应用场景,高并发场景请使用epoll机制。

  • select采用轮询的方式获取读,写,异常事件,轮询的方式效率低,不管文件事件是否就绪,都需要去做检测。

  • select位图设置和获取采用覆盖方式,用户输入的读,写,异常位图会被内核修改,编程非常容易出错,可参考select实现原理图分析,所以每次调用select之前都要重新设置位图。

  • select执行完后会返回剩余超时时间,剩余超时时间会覆盖原来的超时时间,导致超时机制异常。可参考select实现原理图分析,所以每次调用select之前都要重新设置超时时间。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1251448.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

yolov5利用yaml文件生成模型

一、yolov5的yaml文件构成 yaml文件如下图 不论是backbone还是head,每一行都由一个列表组成,列表里面有四个元素,另外,还有两个参数depth和width。在搭建模型的时候,会利用每一行的信息生成一个模块,并按照…

Word文档排版常见问题汇总(公式图表乱码、Visio插图空白区域)

Word文档排版常见问题汇总 1. 公式图表乱码2. Visio图插入Word中,图中空白区域大3. visio 画图插入Word 中只显示{代码},不显示图片4.部分期刊要求 行连续编码(The manuscript text must be line-numbered continuously)5. 要求图…

cocos浏览器测试正常,但到了抖音、微信小游戏事件无响应、无法操作的bug原因及解决办法

本篇文章主要讲解:cocos游戏引擎,浏览器测试时弹出框好好的,无任何报错,构建项目到抖音、微信小游戏时无法弹出弹出框,但又无报错的问题原因及解决办法。 日期:2023年11月25日 作者:任聪聪 问题…

移动家庭云电脑只能24小时不关机

DD转换Linux也不行,北京地区套餐为家庭云电脑畅享版月包,客服回复目前只能设置24小时不关机。 24小时必须关机这是很严重的问题,不能随时保持在线连接,也没有公网IP。

一篇文章完成Hbase入门

文章目录 一、简介1、数据模型结构2、物理存储结构3、数据模型4、基本架构 二、安装1、下载解压安装包2、修改配置文件3、启动服务(单机、集群)4、配置高可用(HA) 三、命令行操作1、建表2、新增/更新数据3、查看表数据4、删除数据5、修改默认保存的数据版本 四、架构1、RegionS…

吴恩达《机器学习》10-4-10-5:诊断偏差和方差、正则化和偏差/方差

一、诊断偏差和方差 在机器学习中,诊断偏差和方差是改进模型性能的关键步骤。通过了解这两个概念,能够判断算法的问题究竟是欠拟合还是过拟合,从而有针对性地调整模型。 1. 概念理解 偏差(Bias): 表示模…

Springboot3+vue3从0到1开发实战项目(一)

一. 可以在本项目里面自由发挥拓展 二. 知识整合项目使用到的技术 后端开发 : Validation, Mybatis,Redis, Junit,SpringBoot3 ,mysql,Swagger, JDK17 ,JWT,项目部署 前端开发: Vue3,Vite&am…

RK3568驱动指南|第七篇-设备树-第70章 参考文档:设备树bindings

瑞芯微RK3568芯片是一款定位中高端的通用型SOC,采用22nm制程工艺,搭载一颗四核Cortex-A55处理器和Mali G52 2EE 图形处理器。RK3568 支持4K 解码和 1080P 编码,支持SATA/PCIE/USB3.0 外围接口。RK3568内置独立NPU,可用于轻量级人工…

微信公众号快速接入大模型

今天找到一个可以快速将大模型接入公众号的方法,现在跟大家分享一下。 如何让微信公众号接入大模型文案创作能力,实现类似ChatGPT文案创作功能。方法其实很简单,只需打开地址“http://www.botaigc.cn:8900/mpauth”,用微信扫码即可…

5G NSA注册解析及图标显示方案

5G NSA注册解析及图标显示方案 1. NSA注册流程解析1.1 NSA注册流程1.2 NAS消息信元变化1.3 UE能力信元变化1.3.1 第一次UE能力查询1.3.2 后续UE能力查询1.3.3 UE能力过滤器解析 1.4 UE测量配置1.5 SCG添加消息解析1.6 SCG添加成功1.7 Split Bearer承载的建立1.8 NR协议查询索引…

Linux | 重定向 | 文件概念 | 查看文件 | 查看时间 | 查找文件 | zip

Linux | 重定向 | 文件概念 | 查看文件 | 查看时间 | 查找文件 | zip 文章目录 Linux | 重定向 | 文件概念 | 查看文件 | 查看时间 | 查找文件 | zip一、more1.1 输出重定向>和>>1.2 输入重定向< 二、 再谈一切皆文件三、less指令【重要】四、head指令五、tail指令…

长寿秘诀揭秘!7个长寿特征,能占1个都是福!

一项涵盖了约72万人的美国退伍老兵的全面性研究&#xff0c;揭露了有这7个特征的人&#xff0c;更易长寿&#xff0c;寿命甚至可延长20多年。 卡尔伊利诺医学院退伍军人事务部健康科学专家研究指出&#xff0c;在中年以后&#xff0c;有这7个特征的人多数比较长寿&#xff0c;…

人工智能 -- 神经网络

1、什么是神经网络 什么是人工智能&#xff1f;通俗来讲&#xff0c;就是让机器能像人一样思考。这个无需解释太多&#xff0c;因为通过各种科幻电影我们已经对人工智能很熟悉了。大家现在感兴趣的应该是——如何实现人工智能&#xff1f; 从1956年夏季首次提出“人工智能”这…

算法基础之滑动窗口

滑动窗口 主要思想&#xff1a;单调队列 保证队列中下标跨度始终为3个数 q[N]维护数组中元素下标 方便判断窗口大小 #include<iostream>#include<algorithm>using namespace std;const int N1000010;int a[N],q[N];int n,k,hh,tt-1;int main(){cin>>n>…

mysql忘记密码,然后重置

数据库版本8.0.26 只针对以下情况 mysql忘记了密码&#xff0c;但是你navicat之前连接上了 解决方法&#xff1a; 第一步&#xff0c;选中mysql这个数据库&#xff0c;点击新建查询 第二步&#xff1a;重置密码 alter user rootlocalhost IDENTIFIED BY 你的密码; 然后就可…

RK WiFi部分信道在部分地区无法使用的原因

不同国家支持的WiFi信道不一样&#xff0c;需要正确设置wificountrycode 修改路径&#xff1a; device\rockchip\common\BoardConfig.mk 修改内容&#xff1a;androidboot.wificountrycodeXX 该属性会被解析为 ro.boot.wificountrycode framework层会在&#xff1a; framewor…

AutoDL tensorboard实现可视化

1.在自己的代码中&#xff0c;writer SummaryWriter(../tf-logs)&#xff0c;具体位置看自己在哪个路径下 我的云服务器下event保存在这里&#xff0c;程序跑起来之后点开这个文件夹就能看见events 2.在容器实例中选择AutoPanel 3.选择tensorboard打开即可看见 4.出现问题 打…

浅谈电力设备智能无线温度检测系统

安科瑞 华楠 摘要&#xff1a;在长期工作中&#xff0c;由于设备基础变化、温湿度变化、严重超负荷运行、触点氧化等原因造成的电力设备压接不紧&#xff0c;触头接触部分发生改变。终导致接触电阻增大&#xff0c;造成巨大的风险隐患。本系统将通过无线测温的方式&#xff0c…

【数据分享】2014-2022年我国省市县三级的淘宝村数量(Excel/Shp格式)

电子商务是过去一二十年我国发展最快的行业&#xff0c;其中又以淘宝为代表&#xff0c;淘宝的发展壮大带动了一大批服务淘宝电子商务的村庄&#xff0c;这些村庄被称为淘宝村&#xff01; 之前我们给大家分享了2014-2022年我国淘宝村点位数据&#xff08;可查看之前的文章获悉…

学习了解抽象思维的应用与实践

目录 一、快速了解抽象思维 &#xff08;一&#xff09;抽象思维的本质理解 &#xff08;二&#xff09;系统架构中的重要性 &#xff08;三&#xff09;软件开发中抽象的基本过程思考 意识和手段 抽象的方式 抽象层次的权衡 二、业务中的应用实践 &#xff08;一&…