[转帖]简单介绍四种IO模型

简单,介绍,四种,io,模型 · 浏览次数 : 0

小编点评

**IO模型比较** | 模型 | 描述 | |---|---| |阻塞IO | 当一个网络IO发生(假设是read)时,它会经历两个阶段:①等待数据准备;②将数据从内核拷贝到进程中。 | | 非阻塞IO | 在用户进程这边,用户进程不会阻塞,而是马上就得到了一个结果。 | | 多路复用IO | 多路IO复用模型是一种异步模型,它使用多个线程轮询所负责的所有socket,当某个socket有数据到达了,就通知用户进程。 | | 异步IO | 异步IO模型“真正”的异步IO需要操作系统更强的支持。 |

正文

https://cdn.modb.pro/db/525350

 

当一个网络IO发生(假设是read)时,它会涉及两个系统对象,一个是调用这个IO的进程,另一个是系统内核。

当一个read操作发生时,它会经历两个阶段:

①等待数据准备;

②将数据从内核拷贝到进程中。

为了解决网络IO中的问题,提出了4中网络IO模型:

阻塞IO模型
非阻塞IO模型
多路复用IO模型
异步IO模型

 

阻塞IO模型

在Linux中,默认情况下所有socket都是阻塞的,一个典型的读操作如下图所示:

当应用进程调用了recvfrom这个系统调用后,系统内核就开始了IO的第一个阶段:准备数据。

对于网络IO来说,很多时候数据在一开始还没到达时(比如还没有收到一个完整的TCP包),系统内核就要等待足够的数据到来。而在用户进程这边,整个进程会被阻塞。

当系统内核一直等到数据准备好了,它就会将数据从系统内核中拷贝到用户内存中,然后系统内核返回结果,用户进程才解除阻塞的状态,重新运行起来。所以,阻塞IO模型的特点就是在IO执行的两个阶段(等待数据和拷贝数据)都被阻塞了。

非阻塞IO模型

在Linux中,可以通过设置socket使IO变为非阻塞状态。当对一个非阻塞的socket执行read操作时,读操作流程如下图所示:

从图中可以看出,当用户进程发出 read 操作时,如果内核中的数据还没有准备好,那么它不会阻塞用户进程,而是立刻返回一个错误。

从用户进程角度讲,它发起一个read操作后,并不需要等待,而是马上就得到了一个结果。当用户进程判断结果是一个错误时,它就知道数据还没有准备好,于是它可以再次发送read操作。

一旦内核中的数据准备好了,并且又再次收到了用户进程的系统调用,那么它马上就将数据复制到了用户内存中,然后返回正确的返回值。

所以,在非阻塞式IO中,用户进程其实需要不断地主动询问kernel数据是否准备好。非阻塞的接口相比阻塞型接口的显著差异在于被调用之后立即返回。

多路复用IO模型
多路IO复用,有时也称为事件驱动IO(Reactor设计模式)。它的基本原理就是有个函数会不断地轮询所负责的所有socket,当某个socket有数据到达了,就通知用户进程,多路IO复用模型的流程如图所示:

当用户进程调用了select,那么整个进程会被阻塞,而同时,内核会"监视"所有select负责的socket,当任何一个socket中的数据准备好了,select就会返回。这个时候用户进程再调用read操作,将数据从内核拷贝到用户进程。

这个模型和阻塞IO的模型其实并没有太大的不同,事实上还更差一些。因为这里需要使用两个系统调用(select和recvfrom),而阻塞IO只调用了一个系统调用(recvfrom)。但是,用select的优势在于它可以同时处理多个连接。所以,如果系统的连接数不是很高的话,使用select/epoll的web server不一定比使用多线程的阻塞IO的web server性能更好,可能延迟还更大;select/epoll的优势并不是对单个连接能处理得更快,而是在于能处理更多的连接。

如果select()发现某句柄捕捉到了"可读事件",服务器程序应及时做recv()操作,并根据接收到的数据准备好待发送数据,并将对应的句柄值加入writefds,准备下一次的"可写事件"的select()检测。同样,如果select()发现某句柄捕捉到"可写事件",则程序应及时做send()操作,并准备好下一次的"可读事件"检测准备。

IO多路复用是最常使用的IO模型,但是其异步程度还不够“彻底”,因为它使用了会阻塞线程的select系统调用。因此IO多路复用只能称为异步阻塞IO,而非真正的异步IO。

异步IO模型
“真正”的异步IO需要操作系统更强的支持。如下展示了异步 IO 模型的运行流程(Proactor设计模式):

用户进程发起read操作之后,立刻就可以开始去做其他的事;而另一方面,从内核的角度,当它收到一个异步的read请求操作之后,首先会立刻返回,所以不会对用户进程产生任何阻塞。

然后,内核会等待数据准备完成,然后将数据拷贝到用户内存中,当这一切都完成之后,内核会给用户进程发送一个信号,返回read操作已完成的信息。

IO模型总结
调用阻塞IO会一直阻塞住对应的进程直到操作完成,而非阻塞IO在内核还在准备数据的情况下会立刻返回。

两者的区别就在于同步IO进行IO操作时会阻塞进程。按照这个定义,之前所述的阻塞IO、非阻塞IO及多路IO复用都属于同步IO。实际上,真实的IO操作,就是例子中的recvfrom这个系统调用。

非阻塞IO在执行recvfrom这个系统调用的时候,如果内核的数据没有准备好,这时候不会阻塞进程。但是当内核中数据准备好时,recvfrom会将数据从内核拷贝到用户内存中,这个时候进程则被阻塞。

而异步IO则不一样,当进程发起IO操作之后,就直接返回,直到内核发送一个信号,告诉进程IO已完成,则在这整个过程中,进程完全没有被阻塞。

各个IO模型的比较如下图所示:

 

与[转帖]简单介绍四种IO模型相似的内容:

[转帖]简单介绍四种IO模型

https://cdn.modb.pro/db/525350 当一个网络IO发生(假设是read)时,它会涉及两个系统对象,一个是调用这个IO的进程,另一个是系统内核。当一个read操作发生时,它会经历两个阶段:①等待数据准备;②将数据从内核拷贝到进程中。为了解决网络IO中的问题,提出了4中网络IO

[转帖]IPMItool 简单介绍

IPMItool是一个用于管理和配置,支持智能平台管理接口(IPMI)1.5版和2.0版规范的设备的实用程序。 IPMI是一个开放的标准,监控,记录,回收,库存和硬件实现独立于主CPU,BIOS,以及操作系统的控制权。 服务处理器(或底板管理控制器,BMC)的背后是平台管理的大脑,其主要目的是处理自

[转帖]Redis配置文件介绍

https://www.cnblogs.com/fanqisoft/p/10422381.html Redis在源码包中存放了一个Redis配置实例文件,文件中对各个配置点进行了简单的介绍,我也通过这个文件来对Redis的一些配置进行一些简单介绍。 一.UNITS(单位)【了解】 1.Redis服务

[转帖]测试工具 sysbench (Centos 7.x) for DM数据库

1、简单介绍 sysbench是一个开源,模块化的多线程性能测试工具,可以用来进行硬件环境性能测试,也可进行数据库的性能测试。但是由于需要支持DM测试,所以我们一般使用源码进行编译。 2、运行方法 sysbench通过运行lua脚本进行数据库测试。而每次测试都分为prepare、run、cleanu

[转帖]测试工具 sysbench (Centos 7.x) for DM数据库

1、简单介绍 sysbench是一个开源,模块化的多线程性能测试工具,可以用来进行硬件环境性能测试,也可进行数据库的性能测试。但是由于需要支持DM测试,所以我们一般使用源码进行编译。 2、运行方法 sysbench通过运行lua脚本进行数据库测试。而每次测试都分为prepare、run、cleanu

[转帖]DD硬盘性能相关因素

https://www.jianshu.com/p/a15d7a65c876 本文简单介绍下DD测试硬盘性能时,各个因素的影响 首先列出测试结果 image.png oflag分析--/home dd默认测试会使用buffer io,oflag=direct参数则会跳过buffer I/O,因此通常

[转帖]k8s系列-06-containerd的基本操作

https://www.jianshu.com/p/52a2884594f5 上一篇我们介绍了containerd的安装,本篇我们来简单介绍下如何进行使用。 环境 linux服务器 前置安装 躺过的坑,需要安装下面内容,否则执行ctr run的时候会报错如下: ctr: failed to crea

[转帖]内核探测工具systemtap简介

https://www.bilibili.com/read/cv16655736/ systemtap是内核开发者必须要掌握的一个工具,本文我将简单介绍一下此工具,后续将会有系列文章介绍systemtap的用法。 什么是systemtap 假如现在有这么一个需求:需要获取正在运行的 Linux 系统

[转帖]DNS解析常见问题:如何添加AAAA记录?

很多人在添加解析记录时都会看到有AAAA记录,那什么是AAAA记录呢?它和A记录的区别是什么,我们又该如何添加AAAA记录呢?接下里中科三方将针对这些问题做下简单介绍。 什么是AAAA记录? AAAA记录(AAAA record)是用来将域名解析到IPv6地址的DNS记录。与之相对的A记录只能将域名

[转帖]Jmeter学习笔记(二十三)——生成HTML性能报告

https://www.cnblogs.com/pachongshangdexuebi/p/11759316.html 有时候我们写性能报告的时候需要一些性能分布图,JMeter是可以生成HTML性能报告的。这篇博客,简单介绍下在利用jmeter进行性能测试时,是如何生成HTML的可视化测试报告的