C++ :websocket 通讯下的五种 I/O 模型

2023-11-14

目录

I/O 多路复用(一种同步 I/O 模型)

非阻塞与阻塞

select、poll、epoll

起因

改善

select 与 poll 的差别

I/O 模型

阻塞 I/O 模型

非阻塞 I/O 模型

I/O 多路复用模型

信号驱动 I/O 模型(SIGIO)

异步 I/O 模型(AIO)


I/O 多路复用(一种同步 I/O 模型)

多路(文件句柄)监听+阻塞/非阻塞I/O

一个线程完成多个网络连接(一对多);

一旦某个文件句柄就绪,就能够通知应用程序进行响应读写操作;

没有文件句柄则会阻塞应用程序,交出 CPU;

select、poll、epoll(Linux 最先进的方式)是目前主流的多路复用I/O技术。

非阻塞与阻塞

  • 非阻塞:通过不断的数据检测直到出现数据响应(事件请求)。

  • 阻塞:等待数据响应(事件请求),期间不进行其他处理,直到响应发现;

select、poll、epoll

起因

对于非阻塞,不断检测流来判定事件处理,是非法的,当所有的流都没有 I/O 事件时,非阻塞将会不断运行并浪费 CPU 时间片,从而产生资源浪费,由此通过引进中间层(代理:select、poll)来对流检测进行事件处理(仅仅处理事件检测),如果没有则进行阻塞,由此避免了线程的不断轮询。

改善

对于 select,通过中间层的处理,我们完善了轮询的阻塞,但是并无法知道当前 select 进行的处理事件数量有多少,当假设有全部流事件存在,select 有 O(n) 的无差别轮询复杂度,处理的流越多,无差别轮询时间越长。

不同于忙轮询和无差别轮询,epoll 会把哪个流发生了怎样的 I/O 事件通知我们,属于事件驱动,通过明确指定事件,便可以定位流,从而不再进行轮询操作,而是明确指定对应的流事件处理。

I/O 模型

阻塞 I/O 模型

  • 默认情况下,所有文件操作都是阻塞的;

  • 第一阶段:应用层数据传到 kernel;第二阶段:kernel 复制到 user space

  • 两个阶段一起阻塞,阻塞状态下,程序不会浪费 CPU;

  • recvfrom 只有等到 kernel 中的数据复制到用户进程缓冲区之后才返回并解除阻塞。

非阻塞 I/O 模型

  • 将套接口设置为非阻塞模式,就是在告诉内核,当请求的 I/O 操作后立刻返回,不可用则返回错误。

  • 当数据没有准备好时,内核立即返回 EWOULDBLOCK 错误,第四次调用系统调用时,数据已经存在,这时将数据复制到进程缓冲区中。其中有:不断轮询(polling),类似频繁等待

  • 第一阶段非阻塞,第二阶段必须阻塞

I/O 多路复用模型

  • 由于以上阻塞与非阻塞都会导致接受 fd 的时候无法跳出等待或者阻塞环节,因此在避免多线程启动导致大量浪费资源的条件下,出现了一个进程处理多个 fd 请求的 io 多路复用技术;

  • 此模型用到 select 和 poll 函数,这两个函数也会使进程阻塞;

  • select 先阻塞,有活动套接字才返回,但和阻塞 I/O 不同的是,两个函数可以同时阻塞多个 I/O 操作,而且可以同时对多个读、写操作的 I/O 函数进行检测,直到有数据可读或可写;

  • select被调用后,进程会被阻塞,内核监视所有 select 负责的 socket,当至少有一个 socket的数据准备好(I/O 可用)时,返回可读,由 recvfrom 处理数据。

信号驱动 I/O 模型(SIGIO)

  • 首先我们允许套接口进行信号驱动 I/O ,并安装一个信号处理函数,进程继续运行并不阻塞

  • 数据准备好时,进程会收到一个 SIGIO 信号,可以在信号处理函数中调用 I/O 操作函数处理数据;

  • 数据报准备好读取时,内核就为该进程产生一个 SIGIO 信号

  • 随后既可以在信号处理函数中调用 recvfrom 读取数据报,并通知主循环数据已准备好待处理,也可以立即通知主循环,让它来读取数据报;

  • 优势在于等待数据报到达第一阶段期间,进程可以继续执行,不被阻塞。免去了 select 的阻塞与轮询,当有活跃套接字时,由注册的 handler 处理;

 

异步 I/O 模型(AIO)

  • 进程发起 read 操作之后,立刻就可以开始去做其它的事。而另一方面,从 kernel 的角度,当收到一个 asynchronous read 之后,会立刻返回,不会对用户进程产生任何 block

  • 然后,kernel 会等待数据准备完成,然后将数据拷贝到用户内存,当这一切都完成之后,kernel 会给用户进程发送一个 signal,通知 read 操作完成

工作机制:告诉内核启动某个操作,并让内核在整个操作 (包括第二阶段,即将数据从内核拷贝到用户层进程缓冲区中) 完成后通知我们

  • 与 SIGIO 区别在于:信号驱动 I/O 模型是由内核通知我们何时可以启动一个 I/O 操作,而异步 I/O 模型是由内核通知我们 I/O 操作何时完成
  1. 优点:整个过程都不阻塞,一步到位;非常使用高并发应用;
  2. 缺点:模型复杂,实现、开发难度较大。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++ :websocket 通讯下的五种 I/O 模型 的相关文章

  • 为什么 int8_t 和用户通过 cin 输入显示奇怪的结果[重复]

    这个问题在这里已经有答案了 一小段代码让我发疯 但希望你能阻止我跳出窗外 看这里 include
  • 如何在c++中读取pcap文件来获取数据包信息?

    我想用 C 编写一个程序来读取 pcap 文件并获取数据包的信息 例如 len sourc ip flags 等 现在我找到了如下代码 我认为它会帮助我获取信息 但是我有一些疑问 首先我想知道应该将哪个库添加到我的程序中 然后什么是 pca
  • 确保 StreamReader 不会挂起等待数据

    下面的代码读取从 tcp 客户端流读取的所有内容 并且在下一次迭代中它将仅位于 Read 上 我假设正在等待数据 我如何确保它不会在没有任何内容可供读取时返回 我是否必须设置低超时 并在失败时响应异常 或者有更好的办法吗 TcpClient
  • MVC 在布局代码之前执行视图代码并破坏我的脚本顺序

    我正在尝试将所有 javascript 包含内容移至页面底部 我正在将 MVC 与 Razor 一起使用 我编写了一个辅助方法来注册脚本 它按注册顺序保留脚本 并排除重复的内容 Html RegisterScript scripts som
  • C中的malloc内存分配方案

    我在 C 中尝试使用 malloc 发现 malloc 在分配了一些内存后浪费了一些空间 下面是我用来测试 malloc 的一段代码 include
  • 在 C 中匹配二进制模式

    我目前正在开发一个 C 程序 需要解析一些定制的数据结构 幸运的是我知道它们是如何构造的 但是我不确定如何在 C 中实现我的解析器 每个结构的长度都是 32 位 并且每个结构都可以通过其二进制签名来识别 举个例子 有两个我感兴趣的特定结构
  • 当我们想要返回对象的引用时,为什么我们在赋值运算符中返回 *this 而通常(而不是 this)?

    我正在学习 C 和指针 我以为我理解了指针 直到我看到这个 一方面 asterix 运算符是解引用的 这意味着它返回值所指向的地址中的值 而与号 运算符则相反 它返回值存储的地址记忆 现在阅读有关赋值重载的内 容 它说 我们返回 this因
  • 如何创建包含 IPv4 地址的文本框? [复制]

    这个问题在这里已经有答案了 如何制作一个这样的文本框 我想所有的用户都见过这个并且知道它的功能 您可以使用带有 Mask 的 MaskedTestBox000 000 000 000 欲了解更多信息 请参阅文档 http msdn micr
  • 如何区分用户点击链接和页面自动重定向?

    拥有 C WebBrowser control http msdn microsoft com en us library system windows forms webbrowser aspx在我的 WinForms 应用程序中 并意识
  • 回发后刷新时提示确认表单重新提交。我做错了什么?

    我有一个以空白 默认状态启动的仪表板 我让用户能够将保存的状态加载到仪表板中 当他们单击 应用 按钮时 我运行以下代码 function CloseAndSave var radUpload find radUpload1ID var in
  • 将 Word 文档另存为图像

    我正在使用下面的代码将 Word 文档转换为图像文件 但是图片显得太大 内容不适合 有没有办法渲染图片或将图片保存到合适的尺寸 private void btnConvert Click object sender EventArgs e
  • qdbusxml2cpp 未知类型

    在使用 qdbusxml2cpp 程序将以下 xml 转换为 Qt 类时 我收到此错误 qdbusxml2cpp c ObjectManager a ObjectManager ObjectManager cpp xml object ma
  • 为什么调用非 const 成员函数而不是 const 成员函数?

    为了我的目的 我尝试包装一些类似于 Qt 共享数据指针的东西 经过测试 我发现当应该调用 const 函数时 会选择它的非 const 版本 我正在使用 C 0x 选项进行编译 这是一个最小的代码 struct Data int x con
  • 从 Linux 内核模块中调用用户空间函数

    我正在编写一个简单的 Linux 字符设备驱动程序 以通过 I O 端口将数据输出到硬件 我有一个执行浮点运算的函数来计算硬件的正确输出 不幸的是 这意味着我需要将此函数保留在用户空间中 因为 Linux 内核不能很好地处理浮点运算 这是设
  • R 中的 Websocket

    我设法在 R 中建立到 Mtgox websocket 的连接 规格如下 url https socketio mtgox com mtgox Currency USD https socketio mtgox com mtgox Curr
  • C#:帮助理解 UML 类图中的 <>

    我目前正在做一个项目 我们必须从 UML 图编写代码 我了解 UML 类图的剖析 但我无法理解什么 lt
  • 不同类型指针之间的减法[重复]

    这个问题在这里已经有答案了 我试图找到两个变量之间的内存距离 具体来说 我需要找到 char 数组和 int 之间的距离 char data 5 int a 0 printf p n p n data 5 a long int distan
  • 如何部署“SQL Server Express + EF”应用程序

    这是我第一次部署使用 SQL Server Express 数据库的应用程序 我首先使用实体 框架模型来联系数据库 我使用 Install Shield 创建了一个安装向导来安装应用程序 这些是我在目标计算机中安装应用程序所执行的步骤 安装
  • WebSocket安全连接自签名证书

    目标是一个与用户电脑上安装的 C 应用程序交换信息的 Web 应用程序 客户端应用程序是 websocket 服务器 浏览器是 websocket 客户端 最后 用户浏览器中的 websocket 客户端通过 Angular 持久创建 并且
  • 从列表中选择项目以求和

    我有一个包含数值的项目列表 我需要使用这些项目求和 我需要你的帮助来构建这样的算法 下面是一个用 C 编写的示例 描述了我的问题 int sum 21 List

随机推荐

  • UE4 解决当角色走到一个物体上时会被弹开的问题

    检查被踩物体的碰撞组件Collision那一栏的CanCharacterStepOn是否是Yes 如果不是请更改之 如果没效那就是其他的碰撞问题
  • leetcode 1035. 不相交的线

    2023 8 25 本题可以转化为 求两数组的最长公共子序列 进而可以用dp算法解决 方法类似于这题最长公共子序列 代码如下 class Solution public int maxUncrossedLines vector
  • 关于nltk安装出现的问题!渣渣版

    1 直接在cmd端输入 gt gt gt pip install nltk gt gt gt nltk download 2 在查阅了csdn各种博客后 我到 https github com nltk nltk data 官网上点击Clo
  • stm32 keil实现在线调试ram程序方法

    一 配置步骤 1 在main函数前面添加中断向量表偏移 如keil魔术棒中IROM1设置的是0x24001000 这在主函数前面需偏移到这个地址 可以使用图中函数 也可以直接操作 SCB gt VTOR 0x24001000 后面的值是你存
  • wsl2 拒绝访问(windows10 升级 windows 11 后) 问题解决

    1 临时解决方案 windows 防火墙关闭后重启电脑可访问 2 解决方案 控制面板 程序 启动或关闭windows功能 开启 Hyper v 重启 关闭 适用于Linux的windows子系统 重启 开启 适用于Linux的windows
  • Linux查看用户登陆历史记录(last命令的使用)

    查看某用户的操作历史 cat home username bash history 使用root登陆使用last x可查看用户登陆历史 last 命令 功能说明 列出目前与过去登入系统的用户相关信息 语 法 last adRx f n 帐号
  • python基础知识—集合

    集合 集合与列表 元组类似 可以存储多个数据 但是这些数据是不重复的 具有自动去重功能 集合的格式 变量名 元素1 元素2 元素3 变量 set 可迭代的内容 可迭代内容 gt list str 元组 字典 一 创建集合 1 set1 Tr
  • Win10和Jetson Nano环境下安装Mediapipe-python

    最近因学习需要用到google的mediapipe包进行手部识别 效果不错便想将其移植到jetson nano的ubuntu系统上 坑不少 在这里记录一下过程 步骤 一 Windows10的安装方法 二 Jetson Nano下的安装方法
  • Tomcat无法自动解压缩webapps下的war包

    Tomcat无法自动解压缩webapps下的war包 1 正常描述 把打好的war包放入tomcat gt webapps中 启动tomcat即可自动解压缩war包 然后即可访问 2 问题描述 启动tomcat 可以访问localhost
  • JavaScript引用数据类型之基本包装类型Boolean、Number、String

    JavaScript引用数据类型之基本包装类型 1 Boolean var falseObj new Boolean false 创建Boolean对象 var falseValue false console log typeof fal
  • 【MySQL】sql_mode 模式

    目录 前言 查看 sql mode 方式 查看当前会话的 sql mode 查看全局的 sql mode sql mode 配置属性 ONLY FULL GROUP BY STRICT TRANS TABLES STRICT ALL TAB
  • 一个中年程序员的10年测试人生,进阶测试专家必备5项技能!

    测试架构师成长线路图 第一步 成为互联网时代合格的测试工程师 如果你是入行不满3年的测试工程师 一定对此有迫切需求 此时 你必须迅速掌握被测软件的业务功能与内部架构 并在此基础上运用各种测试方法 尽可能多地发现潜在缺陷 并能够在已知缺陷的基
  • 无符号数 有符号数 与 补码

    无符号数 有符号数 与 补码 本文是深入理解计算机系统这本书里面关于补码有符号数无符号数章节的一个摘要和读书报告 我个人认为这本书关于这一段的表述 要比绝大多数网上的博客甚至是国内教材要深入浅出的多 同时由于markdown的文档表示公式很
  • vue中的动态路由怎么配置

    如何定义动态路由 如何获取传过来的动态参数 一 param方式 配置路由格式 router id 传递的方式 在path后面跟上对应的值 传递后形成的路径 router 123 1 定义路由 在APp vue中
  • 2.2.1 数据结构——矩阵结构、数组结构与数据框

    创建矩阵的函数名为 matrix 其基本语法格式为 matrix data NA nrow 1 ncol 1 byrow TRUE 其中data表示矩阵的元素 nrow和ncol分别表示了矩阵的行数和列数 byrow TRUE表示按行填充
  • Java:Spring、Java、MyBatis常用注解

    Spring 给容器IOC中注入组件 控制层 Controller 业务层 Service 数据访问层 Repository 通用 Component 泛指各种组件 Controller Service Repository都可以称为 Co
  • 第2章 核心技术概览

    运用之妙夺造化 存乎一心胜天工 有人可能会遇到这样的问题 跨境商贸合作中签订的合同 怎么确保对方能严格遵守和及时执行 酒店宣称刚打捞上来的三文鱼 怎么追踪捕捞和运输过程中的时间和卫生 现代数字世界里 怎么证明你是谁 怎么证明某个资产属于你
  • 基于直方图优化的图像增强技术(MATLAB实现)

    前言 直方图均衡是一种图像增强的常用手段 但全局直方均衡经常会给图像带来失真等问题 为了处理相关问题 本文采取了全局直方均衡 局部直方均衡和Retinex算法来对图像进行处理 主函数 img imread img tif In1 Remov
  • 大数加法(C++实现)

    最常规的大数加法 两个数都是非负的整数 思路 用字符串的方式去存储我们需要计算的数 但是要注意的一点就是我们是倒过来存储这个大数的 比如 123456789 我们存储的时候是存成 987654321 为什么要这么干 我觉得是为了便于后面我们
  • C++ :websocket 通讯下的五种 I/O 模型

    目录 I O 多路复用 一种同步 I O 模型 非阻塞与阻塞 select poll epoll 起因 改善 select 与 poll 的差别 I O 模型 阻塞 I O 模型 非阻塞 I O 模型 I O 多路复用模型 信号驱动 I O