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

异步I/O和同步I/O

点外卖” 和 “自己做饭” 的生活场景来类比 Linux 中的 异步 I/O(AIO) 和 同步 I/O(Synchronous I/O)

1. 同步 I/O(Synchronous I/O)—— 自己做饭

场景

假设你饿了,决定 自己做饭

  1. 第一步:去菜市场买菜(相当于 read() 从磁盘读取数据)
    • 你必须亲自去菜市场,站在摊位前等老板把菜给你(阻塞)。
    • 如果菜市场没菜了,你得一直等(数据未就绪时阻塞)。
  2. 第二步:回家做饭(相当于 CPU 处理数据)
    • 买菜回来后,你才能开始洗菜、切菜、炒菜(顺序执行)。
  3. 第三步:吃饭(相当于程序继续执行后续逻辑)
    • 饭做好后,你才能吃(必须等前一步完成)。

同步 I/O 的特点

  • 阻塞:你必须亲自完成每一步,不能同时做其他事(比如不能一边买菜一边炒菜)。
  • 顺序执行:必须按 买菜 → 做饭 → 吃饭 的顺序来,不能跳过或并行。
  • 简单但低效:如果买菜或做饭很慢,你只能干等着,浪费时间。

Linux 中的同步 I/O 例子

  • read() / write():直接读写文件,如果数据没准备好,程序会卡住(阻塞)。
  • epoll() + 非阻塞 I/O:虽然可以同时监控多个文件描述符,但每次读写仍然需要手动检查数据是否就绪(类似“频繁去菜市场看菜到了没”)。

2. 异步 I/O(Asynchronous I/O, AIO)—— 点外卖

场景

假设你饿了,决定 点外卖

  1. 第一步:在手机上下单(相当于提交异步 I/O 请求)
    • 你只需要在美团/饿了么上点“提交订单”(非阻塞),然后可以继续刷抖音、打游戏(程序继续执行其他任务)。
  2. 第二步:外卖小哥送餐(相当于内核在后台处理 I/O)
    • 商家接单、做饭、打包、骑手取餐、送货,这些过程你完全不用管(内核在后台完成 I/O 操作)。
  3. 第三步:收到外卖通知(相当于回调函数或信号通知)
    • 手机“叮”一声,提示“外卖已送达”(通过回调或信号通知程序 I/O 完成)。
    • 你下楼取餐,然后吃饭(程序处理完成后的逻辑)。

异步 I/O 的特点

  • 非阻塞:下单后你可以继续干其他事,不用站在厨房等饭做好。
  • 并行处理:外卖小哥、商家、骑手可以同时工作(内核在后台高效处理 I/O)。
  • 高效但复杂:你需要留手机号(回调函数)或设置提醒(信号),否则可能错过外卖。

Linux 中的异步 I/O 例子

  • io_uring(Linux 5.1+ 推荐)
    • 像“美团外卖”一样高效,支持文件、网络等异步 I/O。
    • 程序提交订单(io_uring_prep_read),然后继续执行其他任务,内核完成后通知(io_uring_wait_cqe)。
  • libaio(较旧)
    • 类似“老式外卖平台”,功能有限,但也能实现异步文件 I/O。

3. 同步 vs 异步:外卖 vs 做饭

对比项同步 I/O(自己做饭)异步 I/O(点外卖)
是否阻塞阻塞(必须亲自等)非阻塞(下单后可以继续玩)
能否并行不能(一步接一步)能(商家、骑手、你同时干活)
效率低(浪费时间等)高(充分利用时间)
复杂度简单(按步骤来)复杂(需要处理通知)
适用场景低并发、简单任务(如单线程脚本)高并发、高性能需求(如 Web 服务器)

4. 实际代码类比

(1) 同步 I/O(自己做饭)

#include <unistd.h>
#include <stdio.h>int main() {char buf[1024];// 阻塞式读取文件(相当于站在菜市场等菜)ssize_t n = read(STDIN_FILENO, buf, sizeof(buf)); if (n > 0) {// 读取完成后才能继续处理(相当于做饭)write(STDOUT_FILENO, buf, n); }return 0;
}
  • 问题:如果 read() 很慢(比如从硬盘读取大文件),程序会卡住,无法做其他事。

(2) 异步 I/O(点外卖)

#include <liburing.h>
#include <fcntl.h>
#include <stdio.h>void callback(struct io_uring_cqe *cqe) {printf("外卖已送达!读取了 %d 字节\n", cqe->res);
}int main() {struct io_uring ring;io_uring_queue_init(32, &ring, 0); // 初始化“外卖平台”int fd = open("test.txt", O_RDONLY);char buf[1024];// 提交异步读请求(相当于下单)struct io_uring_sqe *sqe = io_uring_get_sqe(&ring);io_uring_prep_read(sqe, fd, buf, sizeof(buf), 0);io_uring_submit(&ring); // 告诉内核:“我点单了,你去做吧!”printf("下单成功!继续刷抖音...\n"); // 程序继续执行其他任务// 稍后检查外卖状态(相当于等手机通知)struct io_uring_cqe *cqe;io_uring_wait_cqe(&ring, &cqe);callback(cqe); // 处理完成事件(取外卖)io_uring_cqe_seen(&ring, cqe); // 标记“已取餐”io_uring_queue_exit(&ring);close(fd);return 0;
}
  • 优势:提交请求后,程序可以继续做其他事,内核在后台高效处理 I/O。

5. 总结

  • 同步 I/O(自己做饭):简单但低效,适合简单任务。
  • 异步 I/O(点外卖):高效但复杂,适合高并发场景(如 Nginx、Redis、数据库)。
  • Linux 推荐
    • 高性能文件 I/O:io_uring(现代外卖平台)
    • 网络 I/O:epoll() + 非阻塞 I/O(类似“多线程做饭”)
http://www.dtcms.com/a/308096.html

相关文章:

  • USRP捕获手机/路由器数据传输信号波形(下)
  • 金融专题|某跨境支付机构:以榫卯企业云平台 VPC 功能保障业务主体安全
  • 文档识别算法-文字识别接口-表格还原-图表文字识别API
  • HCIA-Datacom认证笔记:IP路由基础——核心概念与路由分类
  • Amazon Aurora MySQL 8.0 完整指南
  • 一些利用AIOps工具进行云原生技术持续创新的成功案例
  • Python 元编程实战:动态属性与数据结构转换技巧
  • Pycaita二次开发基础代码解析:曲面法线生成、零件加载与材料应用
  • 基于LSTM-GRU混合网络的动态解析:美联储维稳政策与黄金单日跌1.5%的非线性关联
  • AI陪伴的发展现状
  • STM32——HAL 库MDK工程创建
  • 2000-2024年中国1KM分辨率年度植被指数(NDVI、EVI)数据集
  • 万物都有属于自己的律动
  • 公路坑槽检测分析原理和思路
  • 嵌入式开发学习———Linux环境下IO进程线程学习(一)
  • 【0基础PS】Photoshop (PS) 理论知识
  • linux线程互斥和同步
  • 操作系统系统面试常问(内存、快表、相关知识)
  • 中欧建交50周年,中硼医疗领衔中意BNCT合作月,中国尖端技术出海欧洲
  • main函数,常量指针与指针常量,野指针等,void与void的区别
  • Kubernetes 应用部署实战:为什么需要 Kubernetes?
  • Apache Tomcat样例目录session操纵漏洞解读
  • Import Maps 实战指南:无需打包器,浏览器原生模块路径重映射!
  • python 检查带有标题行,以逗号为分隔符的文本文件
  • Vue 的双向数据绑定原理
  • 自我学习----绘制Mark点
  • 解决Pycharm内存一直升高卡死、反应慢、CPU占用高
  • 《通信原理》学习笔记——第六章
  • IntelliJ IDEA 的常用快捷键
  • Git 详细安装配置教程(Windows版)