Unix下可用的五种 I/O 模型
介绍
当TCP客户端同时处理两个输入时:标准输入和TCP套接字,当客户端fgets
(在标准输入上)被阻塞并且服务器进程被终止时,我们遇到了问题。服务器TCP正确地将FIN发送到客户端TCP,但由于客户端进程被禁止从标准输入读取,所以它从没有看到EOF,直到它从套接字读取(可能更晚)。
如果一个或多个 I/O 条件准备好(即,输入准备好被读取,或者描述符能够获得更多输出),我们希望得到通知。此功能称为 I/O 多路复用,由select
和poll
函数以及前者的较新POSIX变体提供,称为pselect
。
在以下场景中,I/O复用通常用于网络应用程序:
- 当客户端处理多个描述符(通常是交互式输入和网络套接字)时
- 当客户端同时处理多个套接字时(这是可能的,但很少见)
- 如果TCP服务器同时处理侦听套接字及其连接的套接字
- 如果服务器同时处理TCP和UDP
- 如果服务器处理多个服务并且可能处理多个协议
I/O复用不仅限于网络编程。许多重要的应用程序都需要这些技术。
I/O模型
我们首先检查Unix下可用的五种 I/O 模型的基本差异:
- 阻塞 I/O.
- 非阻塞 I/O.
- I/O多路复用(
select
和poll
) - 信号驱动 I/O(
SIGIO
) - 异步 I/O(POSIX
aio_
函数)
输入操作通常有两个不同的阶段:
- 等待数据准备就绪。这涉及等待数据到达网络。当数据包到达时,它将被复制到内核中的缓冲区中。
- 将数据从内核复制到进程。这意味着将(就绪)数据从内核缓冲区复制到我们的应用程序缓冲区中
阻塞 I/O模型
最流行的 I/O 模型是阻塞 I/O 模型(我们在前面的部分中使用了所有示例)。默认情况下,所有套接字都是阻塞的。场景如下图所示:
我们在这个例子中使用UDP而不是TCP,因为对于UDP,数据“准备好”读取的概念很简单:要么已经接收到整个数据报,要么没有接收到。使用TCP它会变得更复杂,因为插座的低水位标记等附加变量会起作用。
我们还将recvfrom
系统调用称为区分我们的应用程序和内核,无论如何recvfrom
实现(BSD getmsg
上的系统调用和调用System V上的系统调用的函数)。通常会有一个从应用程序中运行到内核中运行的切换,之后会在一段时间后返回到应用程序。
在上图中,进程调用recvfrom
和系统调用在数据报到达并复制到应用程序缓冲区之前不会返回,或者发生错误。最常见的错误是系统调用被信号中断。我们说过程从调用recvfrom
到返回的整个时间都被阻止。当recvfrom
成功返回时,我们的应用程序处理的数据包。
非阻塞 I/O 模型
当一个套接字设置为非阻塞时,我们告诉内核“当我请求的I / O操作无法在不使进程进入休眠状态时完成时,不要让进程进入休眠状态,而是返回错误”。该图如下:
- 对于前三个
recvfrom
,没有数据要返回,内核立即返回错误EWOULDBLOCK
。 - 我们第四次调用recvfrom,数据报就绪,它被复制到我们的应用程序缓冲区,并
recvfrom
成功返回。然后我们处理数据。
当一个应用程序坐在循环中调用recvfrom
这样的非阻塞描述符时,它被称为轮询。应用程序不断轮询内核以查看某些操作是否已准备就绪。这通常是浪费CPU时间,但偶尔会遇到此模型,通常在专用于一个功能的系统上。
I/O 多路复用模型
通过 I/O 多路复用,我们在这两个系统调用之一中调用select
或poll
阻塞,而不是在实际的 I/O 系统调用中阻塞。该图是 I/O 复用模型的摘要:
我们阻塞调用select
,等待数据报套接字可读。当select
返回套接字可读时,我们然后调用recvfrom
将数据报复制到我们的应用程序缓冲区中。
与阻塞I / O模型相比 *
- 缺点:使用
select
需要两个系统调用(select
和recvfrom
)而不是一个 - 优点:我们可以等待多个描述符准备就绪(参见本章后面的
select
函数)
具有阻塞I / O的多线程 *
另一个密切相关的I / O模型是使用阻塞I / O的多线程。该模型非常类似于上面描述的模型,除了不使用select
阻塞多个文件描述符,程序使用多个线程(每个文件描述符一个),然后每个线程可以自由调用阻塞系统调用recvfrom
。
信号驱动的 I/O 模型
该信号驱动 I/O 模型使用的信号,告诉内核与通知我们SIGIO
信号时,描述符已准备就绪。该图如下:
- 我们首先为信号驱动的 I/O 启用套接字,并使用
sigaction
系统调用安装信号处理程序。此系统调用的返回是立即的,我们的过程继续进行; 它没有被阻止。 - 当准备好读取数据报时,
SIGIO
将为我们的过程生成信号。我们可以:- 通过调用从信号处理程序读取数据报
recvfrom
,然后通知主循环数据已准备好处理 - 通知主循环并让它读取数据报。
- 通过调用从信号处理程序读取数据报
这个模型的优点是我们在等待数据报到达时不会被阻塞。主循环可以继续执行,只需等待信号处理程序通知数据已准备好处理或数据报已准备好被读取。
异步 I/O 模型
异步 I/O 由POSIX规范定义,并且已经协调了各种标准中出现的实时函数的各种差异,这些差异汇集在一起形成当前的POSIX规范。
这些函数通过告诉内核启动操作并在整个操作(包括从内核到缓冲区的数据副本)完成时通知我们来工作。这个模型和信号驱动的 I/O 模型的主要区别在于,通过信号驱动的 I/O,内核告诉我们何时可以启动 I/O 操作,但是使用异步 I/O,内核告诉我们 I/O 操作完成时。请参见下图,例如:
我们调用
aio_read
(POSIX异步 I/O 函数以aio_
或开头lio_
)并传递以下内核:- 描述符,缓冲区指针,缓冲区大小(相同的三个参数
read
), - 文件偏移量(类似于
lseek
), - 以及如何在整个操作完成时通知我们。
此系统调用立即返回,并且在等待 I/O 完成时不会阻止我们的进程。
- 描述符,缓冲区指针,缓冲区大小(相同的三个参数
我们假设在这个例子中,我们要求内核在操作完成时生成一些信号。在将数据复制到我们的应用程序缓冲区之前,不会生成此信号,这与信号驱动的 I/O 模型不同。
I/O 模型的比较
下图是五种不同 I/O 模型的比较。
前四个模型之间的主要区别在于第一个阶段,因为前四个模型中的第二个阶段是相同的:recvfrom
当数据从内核复制到调用者的缓冲区时,进程被阻塞。但是,异步 I/O 处理两个阶段,与前四个不同。
同步I/O与异步I/O
POSIX将这两个术语定义如下:
- 同步 I/O 操作会导致请求进程被阻塞,直到 I/O 操作完成。
- 异步 I/O 操作不会导致请求进程被阻止。
使用这些定义,前四个I/O模型(阻塞,非阻塞,I/O多路复用和信号驱动I/O)都是同步的,因为实际的I/O操作(recvfrom
)会阻止进程。只有异步I/O模型匹配异步I/O定义。
Unix下可用的五种 I/O 模型的更多相关文章
- Unix下 五种 I/O模型
Unix下共有五种I/O模型: 1. 阻塞式I/O 2. 非阻塞式I/O 3. I/O复用(select和poll) 4. 信号驱动式I/O(SIGIO) 5. 异步I/O(POSIX的aio ...
- I/O模型之一:Unix的五种I/O模型
目录: <I/O模型之一:Unix的五种I/O模型> <I/O模型之二:Linux IO模式及 select.poll.epoll详解> <I/O模型之三:两种高性能 I ...
- []转帖] 浅谈Linux下的五种I/O模型
浅谈Linux下的五种I/O模型 https://www.cnblogs.com/chy2055/p/5220793.html 一.关于I/O模型的引出 我们都知道,为了OS的安全性等的考虑,进程是 ...
- Unix网络编程中的五种I/O模型_转
转自:Unix网络编程中的的五种I/O模型 下面主要是把unp第六章介绍的五种I/O模型. 1. 阻塞I/O模型 例如UDP函数recvfrom的内核到应用层.应用层到内核的调用过程是这样的:首先把描 ...
- 转:Windows Socket五种I/O模型
原文转自: Windows Socket五种I/O模型 Winsock 的I/O操作: 1. 两种I/O模式 阻塞模式:执行I/O操作完成前会一直进行等待,不会将控制权交给程序.套接字 默认为阻塞模 ...
- Windows Socket五种I/O模型
转载:http://www.cnblogs.com/tianzhiliang/archive/2010/08/31/1813637.html 如果你想在Windows平台上构建服务器应用,那么I/O模 ...
- 你可以这么理解五种I/O模型
因为项目需要,接触和使用了Netty,Netty是高性能NIO通信框架,在业界拥有很好的口碑,但知其然不知其所以然. 所以本系列文章将从基础开始学起,深入细致的学习NIO.本文主要是介绍五种I/O模型 ...
- Linux五种I/O模型性能分析
转载自:http://blog.csdn.net/jay900323/article/details/18141217/ socket阻塞与非阻塞,同步与异步 作者:huangguisu 1. 概念理 ...
- 五种I/O模型的学习
来自 http://www.52im.net/thread-1935-1-1.html 4.互联网服务端处理网络请求的原理 首先看看一个典型互联网服务端处理网络请求的典型过程:<ignore ...
随机推荐
- 优化API接口响应速度
前言 API接口响应慢? SLA一直提不上去? 其实这是后端程序员想进阶必须要跨过去的坎:就是把它优化掉. 那么这其中到底有没有套路呢?答案是:有的. 本文将介绍目前正在用并且十分“无脑”有效的这个套 ...
- 在线研讨会预热 | 基于ASPICE&CNAS的单元测试介绍
随着新能源车.智能驾驶技术的快速发展,软件本身复杂度越来越高,应用场景也是复杂多样,如何保证软件质量对我们来说是一个严峻的挑战.软件测试作为软件质量保证的重要手段,被各大整车厂和供应商 ...
- CCS设置第一个li的元素与其他li样式不同
<div class="ly-content-list"> <ul> <li> <div class="title"& ...
- 0029redis单机版环境搭建
linux环境下安装单机版redis,主要分为如下几步: 1. 安装gcc 2.下载安装包 3.解压安装包 4.进入解压目录并执行make和make install命令 5.查看默认安装目录 6.更改 ...
- 《Exception团队》第七次作业:团队项目设计完善&编码
一.项目基本介绍 项目 内容 这个作业属于哪个课程 任课教师博客主页链接 这个作业的要求在哪里 作业链接地址 团队名称 Exception 作业学习目标 1.掌握软件编码实现的工程要求 作业任务 1. ...
- SVM: 相对于logistic regression而言SVM的 cost function与hypothesis
很多学习算法的性能都差不多,关键不是使用哪种学习算法,而是你能得到多少数据量和应用这些学习算法的技巧(如选择什么特征向量,如何选择正则化参数等) SVM在解决非线性问题上提供了强大的方法. logis ...
- C变量作用域的分类和优先级
变量从高到低的优先级以下面展示: 1.文件作用域:变量在全局从文件开头到结尾一直有效即全局变量 2.函数作用域也称局部变量 3.代码块作用域:用{}花括号内的定义的变量:都是在代码块{}中有效 如:i ...
- 2019暑期金华集训 Day7 动态规划
自闭集训 Day7 动态规划 LOJ6395 首先发现这个树的形态没啥用,只需要保证度数之和是\(2n-2\)且度数大于0即可. 然后设\(dp_{i,j}\)表示前\(i\)个点用了\(j\)个度数 ...
- 下载svn
http://subversion.apache.org/download.cgi?update=201708081800 Windows下载zip,其他系统的下载tar.gz
- python提取计算结果的最大最小值及其坐标
我们在fluent当中后处理的时候,可以通过fluent本身得到某些物理量的最大值和最小值,但是我们却无法确定这些最大值和最小值的具体位置.其实我们可以将求解数据导出以后,借助python求得最大值和 ...