五种I/O模型

I/O模型包含5种

阻塞I/O、非阻塞I/O、I/O复用、事件(信号)驱动I/O、异步I/O

进程想要获取磁盘中的数据,需要发起系统调用,通知内核。因为只有内核才能和磁盘交互。

当进程发起系统调用的时候,系统调用进入内核模式,然后开始I/O操作:

磁盘将数据加载进内核的内存空间;

内核的内存空间的数据copy到用户的内存空间。

调用过程:

进程需要对磁盘中的数据进行操作,会向内核发起一个系统调用,然后改进程会被挂起或者进入睡眠状态,也叫不可中断的睡眠,只有当系统调用的结果完成后,进程会被唤醒。具体过程如下:

  1. 进程向内核发起一个系统调用
  2. 内核接收到系统调用,发现是一个文件的请求,通过磁盘把文件读取出来
  3. 磁盘接收到内核的命令后,把数据拷贝到内核的内存空间
  4. 内核的内存空间接收到数据后,把数据拷贝到用户进程的内存空间
  5. 进程的内存空间获取数据后,给内核发送通知
  6. 内核把接收到的通知回复给进程,这个过程为唤醒进程,然后进程拿到数据,进行后续处理

阻塞:是指系统调用返回结果前,用户进程被挂起,直到系统调用返回结果。

非阻塞:进程发起I/O调用,I/O需要一点时间来完成,进程先去进行其他的操作。没隔一段时间,询问内核数据是否准备结束,结束则进程获取到数据,继续执行,此过程也叫作盲等待。

I/O多路复用select

使用多路复用的原因:某个进程阻塞在多个I/O上,一个进程既要等待从键盘输入信息,又要准备从磁盘装入信息,调用了两个I/O操作,其中一个I/O执行结束,另一个还在阻塞,,导致整个县城依旧处于睡眠状态,此时需要I/O多路复用来解决。

进程在调用I/O的时候,不是直接使用I/O的功能,而是在系统内核中,新增一个系统调用,帮助进程监控多个I/O,一旦一个进程需要系统调用的时候,向内核发起一个特殊的系统调用,这个进程就会被阻塞在这个复用器的调用上面,这个进程此时可以进行后面的操作。帮助进程监控这些I/O的工具就叫做I/O复用器。

Linux中的I/O复用器

select:进程调用的时候,把请求发送给select,可以引发多个,但是最多支持1024个。

poll:没有限制,但是1024个后会导致性能下降。

事件驱动

进程发起调用,通过回调函数,内核会记住是哪个进程申请的,一旦一阶段(磁盘将数据装载到内核的内存中),就可以向这个进程发起通知,这样第一阶段是非阻塞的,第二阶段依旧是阻塞的。

两种机制:

水平触发机制:内核通知进程来读取数据,进程没有读取数据,内核会一次又一次的通知进程。

边缘触发机制:内核只通知进程一次来取数据,进程在超时时间内随时可以取数据,取数据的通知发给进程。(例如:nginx)

异步AIO

只有当数据完全拷贝到用户线程的时候,才向服务进程返回信息。

只有在文件中可以实现AIO,网络异步IO不可实现。

原文地址:https://www.cnblogs.com/avalon-merlin/p/10510466.html