I/O的五种模型总结

I/O的五种模型总结

1. 五种 I/O 模型

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

为什么要发起系统调用?

因为进程想要获取磁盘中的数据,而能和硬件打交道的只能是内核,进程通知内核说我要磁盘中的数据,此过程就是系统调用。

一次I/O的完成的步骤

当进程发起系统调用时,这个系统调用就进入内核模式,然后开始I/O操作。
I/O操作分为两个步骤;

1、磁盘把数据装载到内核的内存空间,

2、内核的内存空间的数据copy到用户的内存空间中(此过程是I/O发生的地方)

以下是进程获取数据的详细图解过程;
在这里插入图片描述
调用过程:

①进程向内核发起一个系统调用,

②内核接收到系统调用,知道是对文件的请求,于是告诉磁盘,把文件读取出来

③磁盘接收到来着内核的命令后,把文件载入到内核的内存空间里面

④内核的内存空间接收到数据之后,把数据copy到用户进程的内存空间(此过程是I/O发生的地方)

⑤进程内存空间得到数据后,给内核发送通知

⑥内核把接收到的通知回复给进程,此过程为唤醒进程,然后进程得到数据,进行下一步操作


根据上面的步骤,我们要清楚:

I/O发生的地方才会出现阻塞或非阻塞


5种I/O 过程图解

阻塞I/O

阻塞:进程发起I/O调用,进程又不得不等待I/O的完成,此时CPU把进程切换出去,进程处于睡眠状态则此过程为阻塞I/O

阻塞I/O系统怎么通知进程?

I/O完成,系统直接通知进程,则进程被唤醒。

在这里插入图片描述
这里我们注意到第二阶段,因为第二阶段才是I/O发生的阶段,这个阶段我们的进程被阻塞了,所以被称为阻塞I/O。

非阻塞I/O

非阻塞:进程发起I/O调用,I/O自己知道需过一段时间完成,就立即通知进程进行别的操作,则为非阻塞I/O

非阻塞I/O,系统怎么通知进程?

每隔一段时间,问内核数据是否准备完成,系统完成后,则进程获取数据,继续执行(此过程也称盲等待)

非阻塞I/O的图解:

在这里插入图片描述

I/O复用

在这里插入图片描述

事件(信号)驱动I/O

水平触发的事件驱动机制:内核通知进程来读取数据,进程没来读取数据,内核需要一次一次的通知进程;

边缘触发的事件驱动机制;内核只通知一次让进程来读取数据,进程可以在超时时间之内随时来读取数据。

nginx就采用了边缘触发的事件驱动机制,这就是为什么nginx的并发性比apache好,当然nginx的性能比apache好,还有其它方面,如nginx支持异步I/O,mmap(内存映射)等等

实践驱动I/O图解:
在这里插入图片描述

异步I/O(asynchronous I/O)

在这里插入图片描述
前四种I/O属于同步操作,最后的一种则属于异步操作
至于为什么,看下一节就知道了。

2. 区分总结

linux系统中,所有的设备读写都可以看做文件的读写来操作,对文件的读写一般要经过内核态和用户态的切换,正因为有切换才导致了IO有同步和异步的说法。

通常来讲IO可以分成两种:

  • 网络的IO
  • 来自文件或者设备的IO

并且完成IO操作可以简单的表述为两个步骤:

  • 发起IO请求
  • 执行IO操作

如何区分是同步IO还是异步IO呢?
看:"执行IO操作"是否阻塞
当请求被阻塞,就是同步IO,否则就是异步IO


比如说,在阻塞I/O中,进程需要发起系统调用,让内核去把磁盘的内容拷贝到内核的内存空间去,这还不够,还需要阻塞等待内核把内核的内存空间内容拷贝到用户内存空间,然后返回进行所需的数据,进程这时才得以继续运行下去,因此这个有阻塞的就是同步I/O。
而异步I/O,比如调用aio_read函数,可以直接发起系统调用,等内核把磁盘数据拷贝到内核地址,再从内核地址拷贝到用户地址,进程才会过来处理这个东西,在此前这个进程都是不会被阻塞的,因此是异步I/O。


同步IO的特点:

  1. 同步IO指的是用户进程触发I/O操作并等待或者轮询的去查看I/O操作是否就绪。
  2. 同步IO的执行者是IO操作的发起者。
  3. 同步IO需要发起者进行内核态到用户态的数据拷贝过程,所以这里必须有阻塞

异步IO的特点:

  1. 异步IO是指用户进程触发I/O操作以后就立即返回,继续开始做自己的事情,而当I/O操作已经完成的时候会得到I/O完成的通知。
  2. 异步IO的执行者是内核线程,内核线程将数据从内核态拷贝到用户态,所以这里没有阻塞

如何区分是阻塞IO还是非阻塞IO呢?
看:发起IO操作是否阻塞
如果阻塞直到完成,就是阻塞IO,否则就是非阻塞IO

五种I/O模型的比较:

在这里插入图片描述

  1. 阻塞I/O,第一阶段和第二阶段都被阻塞;
  2. 非阻塞I/O,第一阶段不阻塞,第二阶段阻塞。但是第一阶段需要轮训请求内核。
  3. I/O复用,第一阶段阻塞,但是不用进程阻塞,用的是select等阻塞,第二阶段阻塞。
  4. 事件驱动I/O,第一阶段不阻塞,通过回调函数或者信号实现,第二阶段阻塞
  5. 异步I/O,第一二阶段都不阻塞。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zedjay_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值