IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者

Linux下常用I/O模型

平凡的世界 2012-05-17 23:31:49 累计浏览 4,571 次
本机暂存

    简介

     Linux异步I/O是Linux内核中提供的一个相当新的增强。它是2.6版本内核的一个标准特性,异步非阻塞I/O背后的基本思想是允许进程发起很多I/O操作,而不用阻塞或等待任何操作完成。稍后或在接收到I/O操作完成的通知时,进程就可以检索I/O操作的结果。

    这并不是一个详尽的介绍,但是我们将试图介绍最常用的一些模型来解释它们与异步I/O之间的区别。下图给出了同步和异步模型,以及阻塞和非阻塞的模型。

     原图已失效

     每个I/O模型都有自己的使用模式,它们对于特定的应用程序都有自己的优点。本节将简要对其一一进行介绍。

    同步阻塞I/O

     最常用的一个模型是同步阻塞I/O模型。在这个模型中,用户空间的应用程序执行一个系统调用,这会导致应用程序阻塞。这意味着应用程序会一直阻塞,直到系统调用完成为止(数据传输完成或发生错误)。调用应用程序处于一种不再消费 CPU 而只是简单等待响应的状态,因此从处理的角度来看,这是非常有效的。

     下图给出了传统的阻塞I/O模型,这也是目前应用程序中最为常用的一种模型。其行为非常容易理解,其用法对于典型的应用程序来说都非常有效。在调用 read 系统调用时,应用程序会阻塞并对内核进行上下文切换。然后会触发读操作,当响应返回时(从我们正在从中读取的设备中返回),数据就被移动到用户空间的缓冲区中。然后应用程序就会解除阻塞(read 调用返回)。

     原图已失效

     从应用程序的角度来说,read 调用会延续很长时间。实际上,在内核执行读操作和其他工作时,应用程序的确会被阻塞。

    同步非阻塞I/O

     同步阻塞I/O的一种效率稍低的变种是同步非阻塞I/O。在这种模型中,设备是以非阻塞的形式打开的。这意味着I/O操作不会立即完成,read 操作可能会返回一个错误代码,说明这个命令不能立即满足(EAGAIN 或 EWOULDBLOCK),如下图所示。

     原图已失效

     非阻塞的实现是I/O命令可能并不会立即满足,需要应用程序调用许多次来等待操作完成。这可能效率不高,因为在很多情况下,当内核执行这个命令时,应用程序必须要进行忙碌等待,直到数据可用为止,或者试图执行其他工作。正如图 3 所示的一样,这个方法可以引入I/O操作的延时,因为数据在内核中变为可用到用户调用 read 返回数据之间存在一定的间隔,这会导致整体数据吞吐量的降低。

    异步阻塞I/O

     另外一个阻塞解决方案是带有阻塞通知的非阻塞I/O。在这种模型中,配置的是非阻塞I/O,然后使用阻塞 select 系统调用来确定一个I/O描述符何时有操作。使 select 调用非常有趣的是它可以用来为多个描述符提供通知,而不仅仅为一个描述符提供通知。对于每个提示符来说,我们可以请求这个描述符可以写数据、有读数据可用以及是否发生错误的通知。

     原图已失效

     select 调用的主要问题是它的效率不是非常高。尽管这是异步通知使用的一种方便模型,但是对于高性能的I/O操作来说不建议使用。

    异步非阻塞I/O

     最后,异步非阻塞I/O模型是一种处理与I/O重叠进行的模型。读请求会立即返回,说明 read 请求已经成功发起了。在后台完成读操作时,应用程序然后会执行其他处理操作。当 read 的响应到达时,就会产生一个信号或执行一个基于线程的回调函数来完成这次I/O处理过程

     原图已失效

     在一个进程中为了执行多个I/O请求而对计算操作和I/O处理进行重叠处理的能力利用了处理速度与I/O速度之间的差异。当一个或多个I/O请求挂起时,CPU 可以执行其他任务;或者更为常见的是,在发起其他I/O的同时对已经完成的I/O进行操作。

同分类推荐文章

  1. Vibe新开源项目 - Vaala AI Gateway (2026-05-17 02:10:19)
  2. SmartPerfetto 架构文章 Q&A:8 个深度技术问答 (2026-04-10 11:00:00)
  3. 让 AI 把我的 PHP 博客重写成 Go (2026-03-27 18:33:54)

查看更多 后端 文章 →

建议继续学习

  1. Linux如何统计进程的CPU利用率 (累计阅读 16,211)
  2. 我的 RHCA 之路 (累计阅读 13,930)
  3. Linux内存点滴 用户进程内存空间 (累计阅读 13,061)
  4. 给程序员新手的一些建议 (累计阅读 13,027)
  5. Linux 性能监控、测试、优化工具 (累计阅读 12,955)
  6. 关于linux内存free的一些事情 (累计阅读 12,759)
  7. ps - 按进程消耗内存多少排序 (累计阅读 12,610)
  8. Google怎么用linux (累计阅读 12,476)
  9. find命令的一点注意事项 (累计阅读 11,787)
  10. Linux Used内存到底哪里去了? (累计阅读 11,750)