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

Linux I/O编程:I/O多路复用与异步 I/O对比

文章目录

    • 0. 引言
    • 1. I/O 模型简介
      • 1.1 阻塞 I/O(Blocking I/O)
      • 1.2 非阻塞 I/O(Non-Blocking I/O)
      • 1.3 信号驱动式 I/O(Signal-Driven I/O)
      • 1.4 多路复用 I/O(I/O Multiplexing)
      • 1.5 异步 I/O(Asynchronous I/O)
    • 2. 多路复用 I/O VS 异步 I/O 分析
      • 2.1 多路复用 I/O
      • 2.2 异步 I/O
      • 2.3 多路复用 I/O 与异步 I/O 的比较
      • 2.4 总结
    • 3. 多路复用 I/O 和异步 I/O示例代码
      • 3.1 多路复用 I/O 示例(`select`)
      • 3.2 异步 I/O 示例(`aio_read`)
      • 3.3 代码说明
    • 4. 参考文档

0. 引言

本文将简要介绍 Linux 中的多路复用 I/O 和异步 I/O 模型,并编写示例代码简述。对于网络 I/O,特别是 UDP 和 TCP,多路复用 I/O(如 selectepoll())通常是更好的选择。而异步 I/O(如 libaio)只建议用在文件和块设备的 I/O 操作。

1. I/O 模型简介

Linux 提供了五种常见的 I/O 模型:阻塞 I/O、非阻塞 I/O、多路复用 I/O、信号驱动 I/O 和异步 I/O。

1.1 阻塞 I/O(Blocking I/O)

阻塞 I/O 是最简单的模型,进程会在 I/O 操作完成之前被挂起。适用于低并发、对性能要求不高的场景。

工作原理

  • 进程发起 I/O 操作,若数据不可用,进程会被阻塞,直到数据准备好。

1.2 非阻塞 I/O(Non-Blocking I/O)

非阻塞 I/O 允许进程继续执行其他任务,当数据不可用时,系统返回一个错误码(如 EAGAIN)。进程可以选择继续做其他事情,或者再次尝试 I/O 操作。

工作原理

  • 进程发起 I/O 操作后,如果数据不可用,系统返回错误码,进程继续执行其他任务。

1.3 信号驱动式 I/O(Signal-Driven I/O)

通过内核向进程发送信号通知数据准备情况,进程可以继续执行其他任务,直到收到信号时再处理数据。

适用场景:不希望主动轮询的应用,通常用于低延迟要求的系统或设备驱动

1.4 多路复用 I/O(I/O Multiplexing)

多路复用 I/O 允许一个进程同时监控多个 I/O 通道,避免因等待 I/O 完成而导致的阻塞。

工作原理

  • 通过 select()poll()epoll() 等系统调用,进程可以同时监控多个 I/O 通道,当某个通道就绪时,进程会被通知。
应用进程 内核 select 系统调用,阻塞 数据未准备 等待数据 数据准备好 返回可读条件 read 系统调用 成功响应 应用进程 内核

1.5 异步 I/O(Asynchronous I/O)

异步 I/O 的核心思想是,进程发起 I/O 操作后,系统立即返回,I/O 操作在后台完成。当操作完成时,系统会通知进程。

工作原理

  • 进程发起异步 I/O 操作,系统立即返回,I/O 在后台进行,完成时通知进程。
应用进程 内核 aio_read 返回 数据未准备 等待数据 数据准备好 通知操作完成 处理数据 应用进程 内核

2. 多路复用 I/O VS 异步 I/O 分析

2.1 多路复用 I/O

工作原理

多路复用 I/O 允许一个进程同时监控多个 I/O 通道。在 Linux 中,常用的系统调用包括 select()poll()epoll()

  • select():适合少量文件描述符,效率较低。
  • poll():与 select() 类似,但支持更多文件描述符。
  • epoll():高效地处理大量并发连接,采用事件驱动机制。

优劣势

多路复用允许单个进程处理多个 I/O 操作,减少线程切换的开销。然而,随着文件描述符数量的增加,轮询的开销也会增加。epoll() 通过事件驱动的方式,在大规模并发场景中表现优异。

2.2 异步 I/O

工作原理

异步 I/O 的关键是,进程发起 I/O 操作后,系统立即返回,后台继续执行 I/O 操作,而进程可以继续执行其他任务。当 I/O 操作完成时,系统通过回调函数、信号或其他机制通知进程。

Linux 中的异步 I/O 接口有两种主要实现方式:

  • POSIX AIO:通过 aio_readaio_write 提交异步 I/O 操作,操作完成后,进程可以通过 aio_erroraio_return 获取结果。需要注意的是,POSIX AIO 在某些 Linux 发行版中可能是基于用户空间的模拟,而不是真正的异步 I/O,这可能会影响其性能。
  • libaio:高效的异步 I/O 接口,直接与内核交互,减少线程上下文切换。libaio 特别适合磁盘和文件系统的异步块读写操作。

带来的挑战

  • 资源管理:异步 I/O 需要额外的内存和控制块,可能导致内存泄漏或资源管理困难。
  • 线程调度:异步 I/O 可能会引入线程切换和上下文切换的开销,尤其在大量小 I/O 操作时,性能可能下降。
  • 错误处理:异步 I/O 错误处理较为复杂,特别是回调嵌套或并发操作时,状态同步问题尤为突出。

2.3 多路复用 I/O 与异步 I/O 的比较

  • 适用场景

    • 多路复用 I/O:适用于网络 I/O 场景,特别是 UDP 和 TCP。epoll() 在处理大量并发连接时表现优异。
    • 异步 I/O:适用于文件和块设备的 I/O 操作,如磁盘读写。libaio 在减少上下文切换和提高磁盘 I/O 性能方面效果显著。
  • 性能和复杂性

    • 多路复用 I/O:简单易用,适合大多数网络应用场景。epoll() 在高并发场景下性能优越。
    • 异步 I/O:虽然性能潜力大,但实现复杂,错误处理和资源管理较为困难。
  • UDP 无连接协议:UDP 本身是无连接协议,内核的非阻塞 I/O 和事件驱动模型已经非常高效。UDP 数据包的发送操作不涉及复杂的连接管理,使用非阻塞 I/O 或事件驱动模型(如 selectepoll)即可高效处理并发。

2.4 总结

对于网络 I/O,特别是 UDP 和 TCP,多路复用 I/O(如 selectepoll())通常是更好的选择。而异步 I/O(如 libaio)只建议用在文件和块设备的 I/O 操作。

3. 多路复用 I/O 和异步 I/O示例代码

3.1 多路复用 I/O 示例(select

这个例子演示了如何使用 select 实现多路复用 I/O,监听多个文件描述符(如标准输入和套接字)。

#include <iostream>
#include <unistd.h>
#include <sys/select.h>
#include <fcntl.h>
#include <string.h>int main() {fd_set read_fds;struct timeval timeout;// 创建标准输入的文件描述符集FD_ZERO(&read_fds);FD_SET(STDIN_FILENO, &read_fds);// 设置 select 的超时,单位是秒和微秒timeout.tv_sec = 5;timeout.tv_usec = 0;int ret = select(STDIN_FILENO + 1, &read_fds, NULL, NULL, &timeout);if (ret == -1) {std::cerr << "select failed!" << std::endl;return -1;} else if (ret == 0) {std::cout << "Timeout: No input within 5 seconds" << std::endl;} else {if (FD_ISSET(STDIN_FILENO, &read_fds)) {char buffer[1024];ssize_t len = read(STDIN_FILENO, buffer, sizeof(buffer) - 1);if (len > 0) {buffer[len] = '\0';std::cout << "Input: " << buffer << std::endl;}}}return 0;
}

3.2 异步 I/O 示例(aio_read

这个例子演示了如何使用异步 I/O 读取文件内容。我们将使用 aio_read 来异步地从文件中读取数据。

#include <iostream>
#include <fstream>
#include <aio.h>
#include <unistd.h>
#include <fcntl.h>
#include <cstring>
#include <errno.h>#define FILE_NAME "test.txt"int main() {// 打开文件int fd = open(FILE_NAME, O_RDONLY);if (fd == -1) {std::cerr << "Failed to open file: " << strerror(errno) << std::endl;return -1;}// 准备异步 I/O 控制块struct aiocb aio;memset(&aio, 0, sizeof(aio));aio.aio_fildes = fd;aio.aio_buf = malloc(1024);  // 分配内存空间用于读取数据aio.aio_nbytes = 1024;aio.aio_offset = 0;// 提交异步读取操作if (aio_read(&aio) == -1) {std::cerr << "aio_read failed: " << strerror(errno) << std::endl;close(fd);return -1;}// 等待异步 I/O 完成while (aio_error(&aio) == EINPROGRESS) {// 在此可以执行其他任务std::cout << "Waiting for I/O to complete..." << std::endl;sleep(1);}// 获取异步 I/O 操作的状态int ret = aio_return(&aio);if (ret == -1) {std::cerr << "aio_return failed: " << strerror(errno) << std::endl;free((void*)aio.aio_buf);close(fd);return -1;}// 输出读取的内容std::cout << "Async read completed, data: " << (char*)aio.aio_buf << std::endl;// 清理资源free((void*)aio.aio_buf);close(fd);return 0;
}

3.3 代码说明

多路复用 I/O (select):

  1. FD_SET()FD_ZERO() 用于设置和清空文件描述符集。
  2. select() 会等待 5 秒钟,如果标准输入文件描述符准备好,可以读取数据。
  3. 如果超时或没有输入,程序会输出“Timeout”。

异步 I/O (aio_read):

  1. 使用 open() 打开一个文件并读取数据。
  2. 设置异步 I/O 控制块 aiocb,并调用 aio_read() 提交异步操作。
  3. 通过 aio_error() 检查 I/O 操作是否正在进行,直到操作完成。
  4. 一旦 I/O 完成,使用 aio_return() 获取结果,并输出异步读取的内容。

编译和运行:

g++ -o async_io async_io.cpp -lrt
./async_io

4. 参考文档

一顿饭的事儿,搞懂了Linux5种IO模型

相关文章:

Linux I/O编程:I/O多路复用与异步 I/O对比

文章目录 0. 引言1. I/O 模型简介1.1 阻塞 I/O&#xff08;Blocking I/O&#xff09;1.2 非阻塞 I/O&#xff08;Non-Blocking I/O&#xff09;1.3 信号驱动式 I/O&#xff08;Signal-Driven I/O&#xff09;1.4 多路复用 I/O&#xff08;I/O Multiplexing&#xff09;1.5 异步…...

Spark Plan 之 SQLMetric

SQLMetric Spark Plan 包含以下基本 方法&#xff0c; /*** return All metrics containing metrics of this SparkPlan.*/def metrics: Map[String, SQLMetric] Map.empty/*** return [[SQLMetric]] for the name.*/def longMetric(name: String): SQLMetric metrics(name)…...

基于YOLOv5模型的火焰识别系统

大家好&#xff0c;YOLOv5模型能够快速准确地检测到火灾火焰&#xff0c;在火灾初期甚至是刚刚出现火苗时就发出警报。这为及时采取灭火措施争取了宝贵的时间&#xff0c;极大地降低了火灾造成的损失。系统可以对特定区域进行持续实时监测&#xff0c;无论白天还是夜晚&#xf…...

多模态AI:开启人工智能的新纪元

在人工智能的璀璨星河中&#xff0c;多模态AI技术正逐渐成为一颗耀眼的明星。随着科技的飞速发展&#xff0c;AI技术正以前所未有的速度迈向新的高峰&#xff0c;其中多模态AI的兴起尤为引人注目。本文将深入探讨多模态AI的定义、技术原理、应用场景以及未来发展趋势。 ps.图…...

麒麟信安支撑2024年电力监控系统网络安全加固培训护航电力网络安全!

在网络安全形势日益复杂的今天&#xff0c;电力行业的网络安全尤为重要。为提升电力监控系统网络安全运维人员的专业技能&#xff0c;由国调中心网安处精心策划&#xff0c;国家电网技术学院组织开展的“2024年电力监控系统网络安全加固培训”于近日圆满结束。麒麟信安作为重要…...

横表和纵表 中的横表

图1 图2...

7个常用的JavaScript数组操作进阶用法

文章目录 1、查找数组中的最大值方法一&#xff1a;使用 Math.max 和展开运算符方法二:使用 for 循环逐一比较 2、查找数组中的第二大值方法一&#xff1a;排序后取第二大值方法二&#xff1a;遍历找到第二大值 3、去除数组中的重复项4、合并两个有序数组并保持有序5、旋转数组…...

Spark的Standalone集群环境安装

一.简介 与MR对比&#xff1a; 概念MRYARNSpark Standalone主节点ResourceManagerMaster从节点NodeManagerWorker计算进程MapTask&#xff0c;ReduceTaskExecutor 架构&#xff1a;普通分布式主从架构 主&#xff1a;Master&#xff1a;管理节点&#xff1a;管理从节点、接…...

Android Glide动态apply centerCropTransform(),transition withCrossFade动画,Kotlin

Android Glide动态apply centerCropTransform(),transition withCrossFade动画,Kotlin import android.graphics.Bitmap import android.os.Bundle import android.widget.ImageView import androidx.appcompat.app.AppCompatActivity import com.bumptech.glide.Glide import …...

shukla方差和相对平均偏差

参考资料&#xff1a;实用统计学【李奉令】 Eberhart-Russell模型、Shukla模型、相对平均偏差稳定性分析比较 相对平均偏差在品种稳定性分析中的作用 1、Shukla方差 生物统计中&#xff0c;用于描述一个群体离散程度的统计量有离差、方差、极差等&#xff0c; 国内品种区域试…...

双指针(二)双指针到底是怎么个事

一.有效的三角形个数 有效的三角形个数 class Solution {public int triangleNumber(int[] nums) {Arrays.sort(nums);int i0,end nums.length-1;int count 0;for( i end;i>2;i--){int left 0;int right i-1;while(left<right){if(nums[left]nums[right]>nums…...

vscode通过remote-ssh连接远程开发机

文章目录 安装扩展注意事项:tips其他参数安装扩展 安装VS Code和SSH-Remote扩展:首先,需要确保你已经在本地计算机上安装了VS Code,并且在扩展市场中搜索并安装了"Remote - SSH"扩展。配置SSH:在本地计算机上,打开VS Code的命令面板(使用快捷键"Ctrl+Shi…...

uniapp实现H5和微信小程序获取当前位置(腾讯地图)

之前的一个老项目&#xff0c;使用 uniapp 的 uni.getLocation 发现H5端定位不准确&#xff0c;比如余杭区会定位到临平区&#xff0c;根据官方文档初步判断是项目的uniapp的版本太低。 我选择的方式不是区更新uniapp的版本&#xff0c;是直接使用高德地图的api获取定位。 1.首…...

SQL HAVING子句

SQL 是一种基于“面向集合”思想设计的语言。HAVING 子句是一个聚合函数&#xff0c;用于过滤分组结果。 1 实践 1.1 缺失的编号 图 连续编号记录表t_seq_record 需求&#xff1a;判断seq 列编号是否有缺失。 SELECT 存在缺失的编号 AS res FROM t_seq_record HAVING COUN…...

计算机视觉基础:OpenCV库详解

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 计算机视觉基础&#xff1a;OpenCV库详解 计算机视觉基础&#xff1a;OpenCV库详解 计算机视觉基础&#xff1a;OpenCV库详解 引…...

UI自动化测试工具(超详细总结)

&#x1f345; 点击文末小卡片 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 常用工具 1、QTP&#xff1a;商业化的功能测试工具&#xff0c;收费&#xff0c;可用于web自动化测试 2、Robot Framework&#xff1a;基于Python可扩展的关…...

AJAX 全面教程:从基础到高级

AJAX 全面教程&#xff1a;从基础到高级 目录 什么是 AJAXAJAX 的工作原理AJAX 的主要对象AJAX 的基本用法AJAX 与 JSONAJAX 的高级用法AJAX 的错误处理AJAX 的性能优化AJAX 的安全性AJAX 的应用场景总结与展望 什么是 AJAX AJAX&#xff08;Asynchronous JavaScript and XML…...

ONLYOFFICE 8.2测评:功能增强与体验优化,打造高效办公新体验

引言 随着数字化办公需求的不断增长&#xff0c;在线办公软件市场竞争愈加激烈。在众多办公软件中&#xff0c;ONLYOFFICE 无疑是一个颇具特色的选择。它不仅支持文档、表格和演示文稿的在线编辑&#xff0c;还通过开放的接口与强大的协作功能&#xff0c;吸引了众多企业和个人…...

Science Robotics 综述揭示演化研究新范式,从机器人复活远古生物!

在地球46亿年的漫长历史长河中&#xff0c;生命的演化过程充满着未解之谜。如何从零散的化石证据中还原古生物的真实面貌&#xff1f;如何理解关键演化节点的具体过程&#xff1f;10月23日&#xff0c;Science Robotics发表重磅综述&#xff0c;首次系统性提出"古生物启发…...

uni-app表格带分页,后端处理过每页显示多少条

uni-app表格带分页&#xff0c;后端处理过每页可以显示多少条&#xff0c;一句设置好了每页显示的数据量&#xff0c;不需要钱的在进行操作&#xff0c;在进行对数据的截取 <th-table :column"column" :listData"data" :checkSort"checkSort"…...

基于STM32设计的矿山环境监测系统(NBIOT)_262

文章目录 一、前言1.1 项目介绍【1】开发背景【2】研究的意义【3】最终实现需求【4】项目硬件模块组成1.2 设计思路【1】整体设计思路【2】上位机开发思路1.3 项目开发背景【1】选题的意义【2】摘要【3】国内外相关研究现状【5】参考文献1.4 开发工具的选择【1】设备端开发【2】…...

【初阶数据结构与算法】线性表之链表的分类以及双链表的定义与实现

文章目录 一、链表的分类二、双链表的实现1.双链表结构的定义2.双链表的初始化和销毁初始化函数1初始化函数2销毁函数 3.双链表的打印以及节点的申请打印函数节点的申请 4.双链表的头插和尾插头插函数尾插函数 5.双链表的查找和判空查找函数判空函数 6.双链表的头删和尾删头删函…...

219页华为供应链管理:市场预测SOP计划、销售预测与存货管理精要

一、华为ISC供应链管理 华为的集成供应链&#xff08;ISC&#xff09;领先实践和SISC&#xff08;Siyuan Integrated Supply Chain&#xff09;架构体现了其在供应链管理领域的深度和广度&#xff0c;以下是7点关键介绍&#xff1a; 全面的供应链视野&#xff1a;华为ISC涵盖…...

mac 安装指定的node和npm版本

mac 安装指定的node和npm版本 0.添加映像&#xff1a; export N_NODE_MIRRORhttps://npmmirror.com/mirrors/node 1、使用 npm 全局安装 n npm install -g n 如果报了sudo chown -R 502:20 "/Users/xxx/.npm" sudo npm install -g n 2、根据需求安装指定版本的 node …...

为什么分布式光伏规模是6MW为界点?

安科瑞 Acrel-Tu1990 最近&#xff0c;能源局颁布了一项规定&#xff0c;明确指出6兆瓦&#xff08;MW&#xff09;及以上的分布式光伏电站必须实现自发自用&#xff0c;自行消纳电力。多个省份的能源局进一步规定&#xff0c;规模超过6兆瓦的电站需按照集中式管理进行操作。此…...

arm64架构的linux 配置vm_page_prot方式

在 ARM64 架构上&#xff0c;通过 vm_page_prot 属性可以修改 UIO 映射内存的访问权限及缓存策略&#xff0c;常见的有非缓存&#xff08;Non-cached&#xff09;、写合并&#xff08;Write Combine&#xff09;等。下面是 ARM64 常用的 vm_page_prot 设置及其对应的操作方式。…...

vue3 + naive ui card header 和 title 冲突 bug

背景描述 最近发现一个 naive ui 上的问题&#xff0c;之前好好的&#xff0c;某一次升级后就出现了一个 bug&#xff0c;Modal 使用 card 布局后&#xff0c;Header Solt 下面的内容不见了&#xff0c;变成了 title&#xff0c;因为这个 solt 里面是有操作 action 的&#xf…...

Ubuntu 22.04.5 LTS配置 bond

本次纯实验&#xff0c;不会讲解bond功能&#xff0c;配置bond mode 1 和 mode 4 如何配置 确定内核模块是否加载 实验使用root用户权限&#xff0c;非root用户使用sudo 调用root权限 rootubuntu22:~# lsmod | grep bonding rootubuntu22:~# modprobe bonding rootubuntu22:~# …...

100种算法【Python版】第58篇——滤波算法之卡尔曼滤波

本文目录 1 算法步骤2 算法示例2.1 示例描述2.2 python代码3 算法应用:二维运动目标跟踪问题滤波算法是用于从信号中提取有用信息、去除噪声或估计系统状态的技术。在时间序列分析、信号处理和控制系统中,滤波算法起着关键作用。 1 算法步骤 卡尔曼滤波(Kalman Filter)的…...

关于几种卷积

1*1卷积 分组卷积&深度可分离卷积 空洞卷积、膨胀卷积 转置卷积 https://zhuanlan.zhihu.com/p/80041030 https://yinguobing.com/separable-convolution/#fn2 11的卷积可以理解为对通道进行加权&#xff0c;对于一个通道来说&#xff0c;每个像素点加权是一样的&am…...

创建网站的好处/企业网站管理系统源码

线上集群目前使用的hadoop版本是CDH4.3.0,已经发生过两次jt的oom异常了&#xff0c;严重影响了线上作业的运行。刚开始的时候&#xff0c;通过减小retirejob的cacheSize和interval来减小jt的堆内存占用&#xff0c;起到了一定的效果&#xff0c;但其实也就是延长了jt宕掉的时间…...

香港公司网站可以备案吗/武汉做seo

emqttd集群设置管理 一、先来看EMQ的文档定义&#xff1a;http://emqtt.com/docs/v1/cluster.html emqttd集群设置管理 假设部署两台服务器s1.emqtt.io, s2.emqtt.io上部署集群: 节点名 主机名(FQDN) IP地址 emqttds1.emqtt.io 或emqttd192.168.0.10 s1.emqtt.io 192.168.0.10 …...

做的比较好的二手交易网站有哪些/网站建设公司排名

效果&#xff1a; 就是点击分享&#xff0c;从右边拉出一个div&#xff0c;再次点击回去。功能很简单。 步骤&#xff1a; 1.引入jquery。 <script src"jquery/jquery-3.1.0.min.js"></script> 2.创建按钮和div。 <button class"buts">分…...

网站整体地图怎么做/网站运维

方法一&#xff1a;jmap 查看堆内存 1. top出占用资源最高的pid 2. jmap -histo:live pid | more 查看堆内存使用情况 3 .jmap -dump:formatb,fileoutfile 3024可以 将3024进程的内存heap输出出来到outfile文件里&#xff0c;再配合MAT&#xff08;内存分析工具&#xff0…...

深圳网上招聘最好的网站/搜索引擎广告优化

关于几个目录&#xff0c;GTK、Shell的目录是&#xff1a;/usr/share/themes&#xff0c;图标的目录是/usr/share/icons。 放到/usr/share/下是全局修改&#xff0c;也就是说如果你换一个账户登陆&#xff0c;也是可以用这些主题文件的。弊端就是操作较复杂&#xff0c;需要sud…...

西安网站设设/aso如何优化

Hadoop教程(一) Hadoop入门教程 1 Hadoop入门教程 Hadoop是Apache开源组织的一个分布式计算开源框架(http://hadoop.apache.org/)&#xff0c;用java语言实现开源软件框架&#xff0c;实现在大量计算机组成的集群中对海量数据进行分布式计算。Hadoop框架中最核心设计就是&#…...