当前位置: 首页 > news >正文

高级IO select 多路转接实现思路

文章目录

  • select 函数
  • fd_set 类型
  • timeval 结构体
  • select 函数的基本使用流程
  • 文件描述符就绪条件
  • 以select函数为中心实现多路转接的思路
  • select 缺陷

select 函数

int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);

select函数是一个用于多路复用的系统调用,用于监视一组文件描述符(fd_set)的状态变化。它可以同时监视多个文件描述符,等待其中任意一个文件描述符准备好进行读、写或异常处理。

参数说明:

nfds:要监视的文件描述符的最大值加1。
readfds:用于监视可读事件的文件描述符集合。
writefds:用于监视可写事件的文件描述符集合。
exceptfds:用于监视异常事件的文件描述符集合。
timeout:超时时间,指定select函数的阻塞时间,可以设为NULL表示永久阻塞,也可以设为指向timeval结构体的指针,设置超时时间。

fd_set 类型

fd_set是一个用于表示文件描述符集合的数据类型,在C语言中使用。它是一个位图(bitmap)类型,用于在多路复用机制中管理文件描述符的就绪状态。

在使用fd_set类型时,需要使用一些宏函数进行相关操作,如FD_ZERO、FD_SET、FD_CLR和FD_ISSET。

FD_ZERO(fd_set *set):将指定的fd_set集合清空,将所有位都设置为0。
FD_SET(int fd, fd_set *set):将指定的文件描述符fd添加到fd_set集合中。
FD_CLR(int fd, fd_set *set):将指定的文件描述符fd从fd_set集合中移除。
FD_ISSET(int fd, fd_set *set):检查指定的文件描述符fd是否在fd_set集合中,并返回相应的状态。

timeval 结构体

timeval结构体定义如下:

struct timeval {time_t tv_sec;  // 秒数suseconds_t tv_usec;  // 微秒数
};

其中,tv_sec表示秒数,tv_usec表示微秒数。在使用timeval结构体时,可以通过设置tv_sec和tv_usec的值来表示相应的时间。

在多路复用机制中,可以将timeval结构体用作select函数的timeout参数,指定select函数的阻塞时间。如果timeout设置为NULL,select函数将会永久阻塞,直到有文件描述符就绪或被信号中断。如果timeout设置为指向timeval结构体的指针,则select函数会在指定的时间内阻塞,超过指定时间后会返回0。

select 函数的基本使用流程

在这里插入图片描述

文件描述符就绪条件

select函数或其他多路复用机制时,可以通过以下条件来判断一个socket是否就绪:

可读条件(Read-ready):当一个socket上有数据可读时,即接收缓冲区中有数据等待读取,这个socket就被认为是可读的。

可写条件(Write-ready):当一个socket上的发送缓冲区有足够的空间可以写入数据时,这个socket就被认为是可写的。

异常条件(Exceptional condition):当一个socket上发生了异常情况,如带外数据到达或连接错误,这个socket就被认为是异常的。

以select函数为中心实现多路转接的思路

在这里插入图片描述

select 缺陷

每次调用select, 都需要手动设置fd集合, 从接口使用角度来说也非常不便
(体现为需要数组数据结构辅助)
每次调用select,都需要把fd集合从用户态拷贝到内核态,这个开销在fd很多时会很大(指select的执行过程)
同时每次调用select都需要在内核遍历传递进来的所有fd,这个开销在fd很多时也很大(指select的执行过程)
select支持的文件描述符数量太小(512 * 8 个bit位)

http://www.lryc.cn/news/249415.html

相关文章:

  • C++学不会?一篇文章带你快速入门
  • 【加密相册】 隐私协议
  • 超越基础:释放 Systemd 的全部潜力【systemd 二】
  • Flask学习二:项目拆分、请求与响应、cookie
  • 6、Qt延时的使用
  • 《Effective C++》条款26
  • np.random.uniform() 采样得到的是一个高维立方体,而不是球体,为什么?
  • 1 时间序列模型入门: LSTM
  • 1-Python与设计模式--单例模式
  • Rust之构建命令行程序(一):接受命令行参数
  • Go 谈论了解Go语言
  • 《C++PrimerPlus》第9章 内存模型和名称空间
  • uniapp上架app store详细攻略
  • 面试:线上问题处理
  • Vue3中快速Diff算法
  • ROS2+STM32小车红外对射光电计数器模块资料
  • Android设计模式--桥接模式
  • 1、分布式锁实现原理与最佳实践(一)
  • Autosar通信实战系列03-NM模块要点及其配置介绍
  • Golang模块管理功能
  • 从零构建属于自己的GPT系列1:文本数据预处理、文本数据tokenizer、逐行代码解读
  • scipy 笔记:scipy.spatial.distance
  • java video audio encoder
  • TypeScript 中声明类型的方法
  • 显示器校准软件BetterDisplay Pro mac中文版介绍
  • Element UI 走马灯 实现鼠标滚动切换页面
  • 在Docker上部署Springboot项目
  • 2024中国眼博会,全国眼康与眼镜品牌加盟展会,北京眼健康展
  • C++学习 --谓词
  • Arkts深入了解运用 LazyForEach【鸿蒙专栏-17】