I/O

I/O交互流程

一个完整的I/O交互流程分为量阶段:1、首先是经过内核空间也就是系统处理,2、然后就到用户空间,也就是应用程序。 20210603123944.jpg 内核空间中存放是内核代码和数据,而进程的用户空间中存放的用户程序的代码和数据,不管是内核孔家还是用户空间,都处于虚拟空间中。Linux使用两级保护机制:0是供内核使用,3级是供用户程序使用。每个进程都有各自的私有空间(0-3G),这个空间未系统中奇特进程是不可见的。最高的1G字节虚拟空间则为所有进程及内核共享。

操作系统运行在内核空间,应用程序运行在用户空间,两者不能简单低使用指针传递数据。因为Linux使用的虚拟内存机制,必须通过系统请求Kernel来协助完成I/O操作,内核会为每个I/O设备维护一个缓冲区,用户空间的数据可能被换出,所以当内核空间使用用户空间的指针,对应的数据可能不在内存中。

对于一个输入操作看来说,进程I/O系统调用后,内核会先看缓冲区内有没有相应的缓存数据,如果没有再到设备中读取,因为设备I/O速度一般较慢,内核缓冲区有数据则直接复制到用户的进程空间,所以一个网络的输入操作通畅包括两个不同的阶段。

  1. 等待网络数据达到网卡,然后将数据读取到内核缓冲区。
  2. 从内核缓冲区复制数据,然后拷贝到用户空间。

I/O有内存I/O、网络I/O和磁盘I/O三种,通常我们说的IO指的是后两者。 Dingtalk_20210613113157.jpg

五种I/O通信模型

在网络环境中,I/O分为:第一步是等待,第二步时数据迁移。

阻塞IO模型

微信截图_20210614210113.png 几乎所有的开发者第一次接触网络编程都是从listen()、send()、recv()开始,这些全部都是阻塞的。

特点在I/O执行的两个阶段(等待数据和拷贝数据)都是阻塞
典型应用阻塞Socket、Java BIO
优点1. 塞挂起不消耗CPU资源,及时响应每个操作
2.难度底,开发应用较容易
3.适合并发量小的网络应用开发
缺点1.不适合并发量大的应用,因为每个请求I/O会阻塞进程
2.需要为每个请求分配一个处理进程以及是响应,系统开销大

非阻塞IO模型

微信截图_20210615090059.png 与阻塞比,当用户进程发出read操作适合,如果内核没有数据准备好,他不会阻塞用户进程,而是立刻返回error。从用户进程角度来讲,它发起一起read操作后,不需要等待,而是马上有一个结果

特点用户进程需要不断的主动轮询内核(kernel)数据准备好了么
典型应用Socket设置了NON BLOCK
优点实现难度低,开发应用想对阻塞I/O模型较难
缺点1.进程轮询调用,消耗CPU的资源
2.适合并发量小且不需要及时响应的网络应用开发

多路复用IO模型

微信截图_20210619125652.png 多个进程的I/O可以注册到一个复用器(Selector)上,当用户进程调用该Selector,Selector会监听注册进程的所有I/O,如果Selector监听的所有I/O再内核缓冲区都没有可读数据,select调用的进程会被阻塞,当任一I/O在内核缓冲区中有可读数据时,select调用就会返回,而后select调用进程可以自己或通知另外的进程再次发起读取I/O,读取内核中准备好的数据,多个进程注册I/O后,只有一个select调用进程被阻塞。

特点对于每一个Socket,一般都设置成非阻塞,但是整个用户的进程其实是一直被阻塞的,只不过进程是被select函数阻塞,而不是被Socket I/O阻塞
典型应用Java Nio,nginx(epoll,poll,select)
优点1. 专一进程解决多个进程I/O的阻塞问题,性能好,Reactor模式
2.适合高并发服务应用开发,一个进程/线程响应多个请求
缺点实现和开发难度较大

信号驱动IO模型

2.png 信号驱动I/O是指进程会预先告知内核,向内核注册一个信号处理函数,然后用户进程返回不阻塞,当内核数据就绪会发送一个信号给进程,用户进程便在信号处理函数中调用I/O读取数据,实际上I/O内核拷贝到用户进程的过程还是阻塞的,信号驱动I/O并没有实现真正的异步,因为通知到进程之后,依然由进程来完成I/O操作。这和后面的异步I/O模型很容易混淆

特点并不符合异常I/O要求,只能算是伪异步,并求实际中并不常用
典型应用应用场景少
优点应用少,不总结
缺点实现和开发难度较大

异步IO模型

1.png 用户进程发起aio_read操作后,给内核传递与read相同的描述符、缓冲区指针、缓冲区大小三个参数及文件偏移,告诉内核当整个操作完成时,如何通知我们立刻可以开始去做其他事。而另一方面,从内核的角度,当它收到一个aio_read之后,首先他会立刻返回,所有不会对用户进程产生阻塞,内核会等待数据准备完成,然后将数据拷贝到用户内存,当这一切都完成之后,内核会给用户进程发送一个信号,告诉他aio_read操作完成。

特点正在实现了异步I/O,是五种I/O模型中唯一的异步模型
典型应用Java7AIO,高性能服务器采用
优点1. 不阻塞,数据一步到位,采用Proactor模式
2.非常适合高性能、高并发应用
缺点1. 需要操作系统的底层支持,Linux2.5内核首现,Linux2.6产品内核核心特征
2.实现和开发应用难度大

已有 0 条评论

    欢迎您,新朋友,感谢参与互动!