网络基础扫盲-多路转发

news2024/12/23 10:02:02

博客内容:多路转发的常见方式select,poll,epoll


文章目录

  • 一、五种IO模型
  • 二、多路转发的常见接口
    • 1.select
    • 2、poll
    • 3、epoll
  • 总结


前言
Linux下一切皆文件,是文件就会存在IO的情况,IO的方式决定了效率的高低。

一、五种IO模型

  • 阻塞IO
    内核将数据准备好之前,系统调用会一直等待。 比较常见的IO方式,在我们使用scanf、cin等函数需要从键盘等外设中获取数据,如果我们一直不输入数据,程序会运行到对应的地方卡住,进行阻塞等待。
  • 非阻塞IO
    非阻塞IO,如果内核数据没有准备好,系统调用任然会返回。系统中的父进程在对于子进程的回收时,参数可以设置非阻塞的。比较形象的说法就是排队时可以听着音乐,时不时的看看是否轮到自己。在阻塞的基础上多了一个对于文件描述符的轮询,对于cpu来说就是比较大的浪费。特定场合下才会被使用。
  • 信号驱动IO
    信号的IO方式,内核将数据准备好后,使用SIGIO信号通知引用程序进行IO操作。常见的就是生产消费模型。
  • 多路转发IO
    多路转接,也叫多路复用。表面看来就是阻塞IO,但是比较不同的是阻塞IO是一对一,而多路转接是多对一。就是广撒网的方式。
  • 异步IO
    在内核数据拷贝完成时,通知程序。值得注意的是信号IO是告知程序什么时候可以进行数据的拷贝。

可以说IO就是等待+读写。IO效率取决于等待的时间。

二、多路转发的常见接口

1.select

函数原型:

int select(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout)
  1. 参数一就是对于所需要监视的最大文件描述符+1。
  2. 第二、三、四个参数分别是对可读文件描述符集合,可写文件描述符集合,异常文件描述符的集合。参数的类型是位图,位图的位置代表的数文件描述符,对应的位置表示对应的文件描述符是否是被监视,不需要的直接置null。在这里插入图片描述
    为了使用方便可以这组fd_set的接口
void FD_CLR(int fd, fd_set *set); // 用来清除描述词组set中相关fd 的位
int FD_ISSET(int fd, fd_set *set); // 用来测试描述词组set中相关fd 的位是否为真
void FD_SET(int fd, fd_set *set); // 用来设置描述词组set中相关fd的位
void FD_ZERO(fd_set *set); // 用来清除描述词组set的全部位
  1. 参数五就是对于这些文件描述符的一种方式。参数直接取值为null表示是阻塞时读取。为0是非阻塞,{n,0} 表示在规定时间内没有事件发生 ,超时就会返回,少于规定时间返回剩余的时间。select是进行IO等待了。
    中间的位图参数是一个输入输出型的参数,如果select返回后会把以前加入但是无事件发生的fd清空,就需要使用一个数组进行数据的保存。
    在使用中每一次都需要手动设置fd集合。需要从用户态拷贝到内核态,在用户态、内核态都需要进行遍历所有的fd。开销比较大。最重要的是select使用的位图结构会存在文件描述符数量受限的情况。

最重要的一点,在使用select函数时,用户需要传递一个数组作为参数,用于存储可读、可写和错误事件的文件描述符集合。这是因为操作系统内核不知道用户需要监视哪些文件描述符,因此用户需要自己维护一个数组来告诉内核要监视哪些文件描述符。而且这个数组需要在每次调用select函数时重新初始化,告诉内核新的监视对象。因此,select需要用户自己维护数组。

2、poll

poll函数原型:

int poll(struct pollfd *fds, nfds_t nfds, int timeout);
// pollfd结构
struct pollfd {
int fd; /* file descriptor */
short events; /* requested events */
short revents; /* returned events */
};

参数说明

  1. fds是一个poll函数监听的结构列表. 每一个元素中, 包含了三部分内容: 文件描述符, 监听的事件集合, 返 回的事件集合。
  2. nfds表示fds数组的长度. 。
  3. timeout表示poll函数的超时时间, 单位是毫秒(ms)
    返回值小于0表示失败,等于0表示poll等待超时。dyu0,表示监听的文件描述符就绪二返回。
    poll在使用上比select简单而且解决了select表示文件描述符表数量受限的问题。但是poll在返回后还是需要轮询pollfd来获取就绪的文件描述符。同时在每次的调用时都需把大量的pollfd结构从用户态拷贝到内核态。连接的大量客户端在同一时刻可能只有很少的处于一个就绪状态。随着监视的描述符数量的增长,效率也会出现线性的下降。

3、epoll

epoll是为了处理大批量的句柄而改进的poll。
使用epoll的三部曲

  1. 调用epoll_create创建一个epoll句柄;
  2. 调用epoll_ctl 将要监控的文件描述符进行注册;
  3. 调用epoll_wait 等待文件描述符就绪
int epoll_create(int size);

参数:自从linux2.6.8之后, size参数是被忽略的.用完之后, 必须调用close()关闭。

int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);

参数:第一个就是epoll模型,epoll_create()的返回值。参数二是表示的动作,通常使用宏来表示

  • EPOLL_CTL_ADD :注册新的fd到epfd中;
  • EPOLL_CTL_MOD :修改已经注册的fd的监听事件;
  • EPOLL_CTL_DEL :从epfd中删除一个fd

参数三是需要监听的文件描述符,参数四是监听文件描述符的什么事件。

int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);

  • 参数events是分配好的epoll_event结构体数组
  • .epoll将会把发生的事件赋值到events数组中 (events不可以是空指针,内核只负责把数据复制到这个events数组中,不会去帮助我们在用户态中分配内存).
  • maxevents告之内核这个events有多大,这个maxevents的值不能大于创建epoll_create()时的size.
  • 参数timeout是超时时间 (毫秒, 0会立即返回,-1是永久阻塞).如果函数调用成功,返回对应I/O上已准备好的文件描述符数目,如返回0表示已超时, 返回小于0表示函数失败。

为啥epoll好?
通过与select的缺点对应比较。

  • 接口方便:虽然拆分了三个函数,但是更加高效,使用select时需要每次都访问自己维护的数组。输入输出的参数进行了分离。
  • 数据拷贝更加的轻量化:在对于文件描述符的添加时不是一直都都需要调用EPOLL_CTL_ADD进行拷贝到内核中的,不会像select一样操作频繁。
  • 事件回调机制:避免使用了遍历,使用的是回调函数机制,就绪的文件描述符结构加入就绪队列中,epoll_wait返回直接访问就绪队列的就是知道哪些文件描述符已经就绪。事件复杂度是O(1)的。
  • 没有数量上的限制。

以上的优点何以见得,epoll的底层原理就是
每一个epoll对象都有一个独立的eventpoll的结构体,用来存放epoll_ctl方法向epoll对象中添加进来的事件。事件挂载到红黑树上,重复添加就是对于红黑树的节点的增,查,改操作。添加的事件都会与外界的设备程序建立回调关系,事件一旦发生就会触发对应的回调函数。回调的方法在内核中ep_poll_callback,它再将发生的事件添加到rdilist双向链表中,双向链表作为epoll_wait的消息队列。对于同一个事件节点是被红黑树和消息队列的俩个数据结构共用的。
在这里插入图片描述
三者之间的对比

特性selectpollepoll
可监视的fd数最大为FD_SETSIZE没有限制没有限制
事件触发方式轮询轮询事件通知
I/O效率一般
内存占用适中
时间复杂度O(n)O(n)O(1)
可移植性跨平台跨平台仅在Linux、BSD等少数平台支持
文件描述符生命周期控制子进程不继承fd子进程不继承fd子进程自动继承fd

总结

select适用于连接数较少的情况,可移植性好,但效率较低;poll效率高于select,但仍然存在遍历fd集合的缺点;epoll适用于连接数较多的场景,且能够避免无用的遍历,效率最高,但只能运行在Linux系统上。

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

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

相关文章

【Solidity】Remix在线环境及钱包申请

好久没有学习区块链方面的知识了,目前通过自学大致掌握了Fabric联盟链的搭建,链码编写、部署,api调用,可以独立开发出一些基于fabric的应用,感觉开发出去中心化的应用还是很有意思的,因为他与之前开发的ssm…

Git 案例(企业如何使用git开发项目)

一、企业中我们是如何开发 1) 入职第一天,管理人员分配/git账号密码 2) 开发人员下载代码即文档/ 根据文档将环境搭建成功 3) 团队一般会给你讲讲项目相关的支持 4) 你接到第一个需求(或者某个功能,一般要经过沟通,分析,设计...等过程) 5) 创建feature分支(一般一个需求对应…

【计算机网络实验/wireshark】tcp建立和释放

wireshark开始捕获后,浏览器打开xg.swjtu.edu.cn,网页传输完成后,关闭浏览器,然后停止报文捕获。 若捕获不到dns报文,先运行ipconfig/flushdns命令清空dns缓存 DNS报文 设置了筛选条件:dns 查询报文目的…

【Java对象】一文读懂 Java 对象庐山真面目及指针压缩

文章目录 版本及工具介绍Java 对象结构对象头mark word 标记字mark word 标记字解析Lock Record class point 类元数据指针 实例数据对齐填充为什么需要对齐填充 常见 Java 数据类型对象分析ArrayListLongStringByteBoolean 其它指针压缩前置知识:32位操作系统为什么…

AI写作软件哪个好?这3个AI写作神器用了都说好!

随着信息时代的快速发展,AI写作早已成为人们创作内容的重要途径之一,在使用AI软件进行创作之前,当然要选择一个优质的写作软件,不过只要你拥有了这3款写作神器,你就能轻松创作出高质量的文章,我们一起来看看…

【uniapp】uview1.x 的 u-upload 上传点击删除隐藏 modal 提示框

uview1.x 版本的 upload 默认在图片成功上传后,再点击右上角删除按钮时会弹出提示框,如图: 但是有时又不需要,想要直接提示删除成功即可,由于官网没有给出点击删除按钮时所调用的钩子函数,又无法操作 DOM&…

【unity小技巧】实现由滑动条控制音量的大小

文章目录 前言开始1.配置BGM2.滑动条3.文本组件4.新增音量控制脚本 完结 前言 这期来一个比较基础的课程,也是比较常用的,unity使用滑动条控制音量的大小 开始 1.配置BGM 2.滑动条 3.文本组件 4.新增音量控制脚本 public class VolumeController : M…

数据库实验:SQL的数据视图

目录 视图概述视图的概念视图的作用 实验目的实验内容实验要求实验过程 视图概述 视图是由数据库中的一个表或多个表导出的虚拟表,其作用是方便用户对数据的操作 视图的概念 视图是一个虚拟表,其内容由查询定义。同真实的表一样,视图包含一…

关于ROS的网络通讯方式TCP/UDP

一、TCP与UDP TCP/IP协议族为传输层指明了两个协议:TCP和UDP,它们都是作为应同程序和网络操作的中介物。 **TCP(Transmission Control Protocol)协议全称是传输控制协议,是一种面向连接的、可靠的、基于字节流的传输…

树莓派4无法进入桌面模式(启动后出现彩色画面,然后一直黑屏,但是可以正常启动和ssh)

本文记录了这段比较坎坷的探索之路,由于你的问题不一定是我最终解决方案的,可能是前面探索路上试过的,所以建议按顺序看排除前置问题。 双十一又买了个树莓派 4B,插上之前树莓派 4B 的 TF 卡直接就能使用(毕竟是一样规…

Java 8 新特性 Stream 的使用场景(不定期更新)

方便在写代码的过程中直接使用,好记性不如好文章,直接 CV 改了直接用。提高 办(摸)公(鱼)效(时)率(间), 不然就直接问 GPT 也不是说不行。 只符合…

win10 + cmake3.17 编译libpng-1.6.34

需要预先编译zlib库当前的根目录为:D:\Depend_3rd_party\libpngx64\ 1. 下载并解压libpng-1.6.34,得到 D:\Depend_3rd_party\libpngx64\libpng-1.6.34 2. 创建build文件夹,install文件夹,得到 D:\Depend_3rd_party\libpngx64\i…

数据库--数据库约束/聚合查询/分组查询/联合查询

前言 逆水行舟,不进则退!!! 目录 数据库约束 聚合查询 分组查询 联合查询 联合查询---内连接与外连接 补充 联合查询用到的代码 数据库约束 not null 约束:在创建表的时候,可以指定列…

【实验记录】为了混毕业·读读论文叭

PR曲线 1. Robust_Place_Recognition_using_an_Imaging_Lidar 在第三节方法中,提到了一些列处理步骤,分析来与vins相似,在vins中是关键帧检索、特征提取、DBoW查询、描述子匹配、PnP RANSAC求解。 第四节的实验部分,没有绘制pr…

MyBatis 详解

目录 1.MyBatis 框架的搭建 1.1 创建数据库和表 1.2 添加 MyBatis 依赖 1.3 设置 MyBatis 配置 1.3.1 设置数据库的连接信息 1.3.2 设置 XML 保存路径和命名格式 1.4 根据 MyBatis 写法完成数据库得操作 1.4.1 定义接口 1.4.2 使用 XML 实现接口 2.MyBatis查询操作 …

手记系列之七 ----- 分享Linux使用经验

前言 本篇文章主要介绍的关于本人在使用Linux记录笔记的一些使用方法和经验,温馨提示,本文有点长,约1.7w字,几十张图片,建议收藏查看。 一、Linux基础使用 1,服务器查看及时日志 tail -500f catalina.out …

npm的使用

package.json 快速生成package.json npm init -y “version”: “~1.1.0” 格式为:「主版本号. 次版本号. 修订号」。 修改主版本号是做了大的功能性的改动 修改次版本号是新增了新功能 修改修订号就是修复了一些bug dependencies "dependencies": {&…

计算机组成与结构-计算机体系结构

计算机体系结构 指令系统 Flynn分类法 SISD(单指令流单数据流) 结构 控制部分:一个处理器:一个主存模块:一个 代表 单处理器系统 SIMD(单指令流多数据流) 结构 控制部分:一个处理…

2022年09月 Python(三级)真题解析#中国电子学会#全国青少年软件编程等级考试

Python等级考试(1~6级)全部真题・点这里 一、单选题(共25题,每题2分,共50分) 第1题 十六进制数100,对应的十进制数为 ?( ) A: 128 B: 256 C: 28 D: 56 答…

基于Qt命令行处理XML文件读写

Qt源码在后面,文本介绍Qt国际化语言和XML # XML基础(一) ## 1、概述 ### 1.1 定义(xml是个啥玩意儿?) XML(extensible Markup Language)俗称差妹儿,专业称之为:可拓展标记语言。 (1)何为标记,指的是一种标记语言,或者标签语言,即用一系列的标签来对数据进行…