简述五种常见的IO模式

一次IO读取操作,分为几个步骤:

  1. 用户线程发送read()请求,从用户态切换到内核态;
  2. 操作系统接收到请求后,通过DMA将数据从磁盘copy到内核缓冲区;
  3. 然后CPU从内核态切换到用户态,将内核缓冲区的数据copy到用户空间;

简单来说,一次IO操作分为数据准备与数据复制两个过程;

阻塞IO(BIO)

所谓阻塞IO,即用户线程发起io读取请求时,操作系统会根据请求准备对应数据,此时,用户线程就会处于阻塞状态。直到操作系统将数据准备完毕并且将数据copy到用户空间,此时用户线程才会解除阻塞状态;
请添加图片描述

非阻塞IO (NIO)

非阻塞IO,相对于阻塞IO,即用户线程发起IO请求时,如果所需的数据未准备好,会直接返回一个error。用户线程不会一直阻塞,在得到响应后,便知道此时数据未准备好,进而继续发起IO请求。直到操作系统将数据准备好并且恰好又收到一次用户线程的IO请求时,数据才得以返回。

非阻塞IO虽然不会阻塞用户线程,但是由于线程会轮询的请求数据,所以会导致CPU占用。
请添加图片描述

多路复用IO

首先明确一点,多路复用IO本身还是会导致用户线程阻塞
请添加图片描述

- 多个客户端的io请求打到服务器上,服务器开启用户线程(单个线程)汇总多个io请求的数据,注册多个socket对应的文件描述符给操作系统,表示“我要监视这些fd是否有IO事件发生(通过select()函数监听),然后用户线程阻塞;

- Select()函数轮序每个socket,判断对应的文件描述符是否是就绪状态,即所需要的数据是否准备好(此期间,在是内核态轮序);

- 直到某个socket的数据准备就绪,然后通知用户线程进行真正的IO读取操作;

实际上,多路复用IO是一种机制,一个线程管理多个连接,无需多余的线程开销和资源维护,一般配合NIO使用才有意义。

信号驱动IO

这个用作了解即可;所谓信号驱动IO;

用户线程发起一次io请求,会在对应的socket注册一个信号函数,此后,用户线程无需阻塞,继续执行其他任务。内核将数据准备就绪时,会给用户线程发送信号,告知数据已经就绪。然后用户线程通过信号函数读取数据。

异步IO

用户线程发起一次io请求,然后可以直接做其他的任务。内核在收到一个read请求之后,会立即返回,告知用户线程:我已收到你的请求,剩下的交给我。此后,内核会等待数据准备完成,并且将数据copy到用户线程,当上述操作完成后,再给用户线程发送信号,read操作已经全部完成,你可以直接使用了。整个过程,无需用户线程参与。
请添加图片描述

信号驱动IO与异步IO的区别可以立即为:

货车司机拉货,货车开到指定地点后,需要等待货物准备好:

  1. 信号驱动IO: 货仓的工人把货物准备好,堆积在地上,此时货车司机可以做其他事情,比如保养车辆等,货物准备好了,电话通知司机可以把货搬车上运走了。
  2. 异步IO: 司机给车辆做保养,货仓工人把货从仓库帮忙给搬到车上,司机保养完可以直接开车走人,全程无需参与货物的搬运。
  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值