【I/O】Unix IO 介绍

IO 模型(一)

Unix IO

一个输入操作共包含两个阶段:

  • 等待数据准备好
  • 从内核将数据复制到进程

对于一个套接字上的输入操作,通常第一步是等待数据从网络中到达,当数据到达时,先将数据复制到内核缓冲区中,第二步就是将数据从内核缓冲区中复制到应用进程的缓冲区中

Unix IO 有五个模型:

  • 阻塞式 IO
  • 非阻塞式 IO
  • IO 多路复用(select 和 poll)
  • 信号驱动 IO
  • 异步 IO(AIO)

阻塞式 IO

阻塞式 IO 的阻塞说的是,在进行 IO 操作时,应用进程将会阻塞,直到数据被复制到进程缓冲区中才返回。

在阻塞式 IO 中,应用进程阻塞时并不意味着其他程序也被阻塞,其他的程序依旧可以运行,因此阻塞式 IO 在阻塞过程中不消耗 CPU 资源,这种模型的效率会比较高。

下面的代码中,recvfrom 用于接收 Socket 传来的数据,并复制到应用进程缓冲区。这里的 recvfrom 当做系统调用

c 复制代码
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);

非阻塞式 IO

非阻塞式 IO 的非阻塞是,在进行 IO 操作时,应用进程不会阻塞,会系统调用定时轮询检查数据是否准备好,若没准备好内核会返回一个错误码,这种方式 CPU 会处理更多的系统调用,因此效率会比较低

IO 多路复用

使用 select 或是 poll 等待数据,并且可以等待多个套接字中任何一个变为可读,这个过程会进行阻塞,当某个套接字可读时返回,在使用 recvfrom 进行复制

IO 多路复用可以让单个进程有处理多个 IO 事件的能力,例如,一个 Web 服务器没有多路复用,每一个 Socket 连接都要创建一个线程去处理,如果同时有几万个连接,那么就需要创建相同数量的线程。

信号驱动 IO

应用进程使用 sigaction 进行系统调用,内核立即返回,应用进程可以继续执行,也就是说,在内核等待数据到达阶段应用进程是非阻塞的,可以继续执行。内核在数据到达后,会向应用进程发送 信号 ,应用进程在收到信号后,会在信号处理程序中调用 recvfrom 进行系统调用将数据复制到应用进程。

异步 IO

应用程序进行 aio_read 系统调用,立即返回,应用进程继续执行不会阻塞,内核在完成所有操作之后,向进程发送信号,异步 IO 的信号通知应用进程 IO 完成,而信号驱动 IO 的信号是通知应用进程可以开始 IO

同步 IO 与 异步 IO

  • 同步 IO:应用进程在调用 recvfrom 时会阻塞

  • 异步 IO:不会阻塞

阻塞式 IO、非阻塞式IO、IO多路复用、信号驱动 IO 都是同步 IO,虽然非阻塞式 I/O 和信号驱动 I/O 在等待数据阶段不会阻塞,但是在之后的将数据从内核复制到应用进程这个操作会阻塞。

相关推荐
用户49055816081251 小时前
lvs会话同步
后端
用户49055816081251 小时前
linux内核网络协议栈报文的处理过程
后端
夜宵饽饽1 小时前
上下文工程实践 - 工具管理(上篇)
javascript·后端
ERP老兵_冷溪虎山1 小时前
Python/JS/Go/Java同步学习(第十三篇)四语言“字符串转码解码“对照表: 财务“小南“纸式转码术处理凭证乱码崩溃(附源码/截图/参数表/避坑指南)
java·后端·python
努力的小郑1 小时前
MySQL索引(四):深入剖析索引失效的原因与优化方案
后端·mysql·性能优化
智商偏低1 小时前
ASP.NET Core 中的简单授权
后端·asp.net
练习时长一年2 小时前
搭建langchain4j+SpringBoot的Ai项目
java·spring boot·后端
bobz9652 小时前
Proxmox qemu-server
后端
编码浪子2 小时前
趣味学RUST基础篇(异步补充)
开发语言·后端·rust
songroom2 小时前
Rust : 关于Deref
开发语言·后端·rust