五种IO类型简单了解

编程过程中经常会遇到 IO,而且各种技术框架底层也是各种IO的应用。这里简单整理下。

IO类型

参考《UNIX网络编程》,IO一共分五种类型

  • 阻塞IO(bloking IO)

  • 同步非阻塞IO(synchronous non-blocking IO)

  • 信号驱动式IO(signal-driven IO)

  • 多路复用IO(multiplexing IO)

  • 异步IO(asynchronous IO)

前四种为同步IO,最后一种为异步IO。

 

概念

这里简单介绍几个概念,具体内容可以学习《深入理解计算机系统》一书。

用户空间

内核空间

进程切换

进程阻塞

缓存 IO

操作系统会将 IO 的数据缓存在文件系统的页缓存( page cache )中。

整个过程:

一、硬盘上的数据会先被拷贝到操作系统内核的缓冲区中;

二、然后再从操作系统内核的缓冲区拷贝到应用程序的地址空间。

前者是数据准备,后者是数据复制。两个步骤不同的实现方式组合,就构成了上边说的五种IO类型。

(值得一说 kafka 中用的零拷贝就是省略了第二步,直接将OS内核缓冲区的数据发送给网卡)

 

IO类型

下边来一一介绍。

阻塞IO

即最简单的IO,从名字就可以知道它直接阻塞用户进程直到系统返回数据。

也就是说,两个步骤完成之前,用户进程都是阻塞的。

如图:

 

优点:数据可用立刻返回,没有延迟;调用简单;

缺点:整个过程,用户进程都处于阻塞等待状态。

 

同步IO

也就是同步非阻塞IO,是一种轮询(polling)方式。

在第一步,用户进程每次read 时,都是立即直接返回 EAGAIN 或 EWOULDBLOCK 错误,直到操作系统缓存中准备好。

在第二步,还是会阻塞,直到数据从操作系统内核缓冲区复制到用户程序内存空间。

如图:

 

这种方式下,用户进程定期轮询,每次轮询都相当于一个小的阻塞(尤其是网络请求)。而在轮询间隔期间可以做其他的事情。

 

信号驱动式IO

所谓信号驱动,其实就是提前向内核注册,然后收到通知后回调处理函数。

一、用户进程预先告知内核、并向内核注册一个信号处理函数,然后用户进程返回。这一步骤不阻塞。 二、当内核数据就绪时会发送一个信号给进程,用户进程便在信号处理函数中调用IO读取数据到用户空间。这一步还是阻塞的。

注意:信号驱动IO并不是真正的异步,因为在第二步还是需要用户进程进行IO操作。

缺点:需要一个注册回调机制,开发实现成本高。

如图:

 

 

多路复用

因为Java NIO、Ngnix、NodeJS、Redis 等大火的原因,多路复用可以说众所周知。平时所说的select,poll,epoll就是它。

简单来说就是利用 selector 实现一个进程即 select() 函数循环监听一个文件描述符集合,当某个文件描述符就绪,则对其进行处理。

如图:

 

在这两个过程中,select 只负责等待,recvfrom 负责从操作内核空间拷贝数据。

从这点来说多路复用跟阻塞IO很像,但因为selector可以对多个文件描述符进行阻塞监听,所以效率比阻塞IO的高。

 

异步IO

顾名思义,IO过程是异步的

如图:

 

一、用户进程发起 aio_read 调用并给内核传递描述符、缓冲区指针、缓冲区大小三个参数,然后系统调用立刻返回。因此用户进程可以继续工作。 二、当系统收到一个aio_read调用后立刻返回,之后内核等待数据准备完成,并将数据拷贝到用户内存。 三、之后系统内核会给用户进程发送一个signal或执行一个基于线程的回调函数来完成这次 IO 处理过程。

异步IO有点类似信号驱动IO,区别在于

  • 信号驱动IO是由内核通知我们何时可以启动一个IO操作

  • 异步IO模型是由内核告知我们IO操作何时完

 

IO对比,图片来源于书

 

综合以上

阻塞程度:阻塞IO > 同步非阻塞IO > 多路复用IO > 信号驱动IO > 异步IO,效率是由低到高的。

发展过程:

 

更多扩展

Reactor模式

是一种处理一个或多个客户端并发交付服务请求的事件设计模式。当请求抵达后,服务处理程序使用I/O多路复用策略,然后同步地派发这些请求至相关的请求处理程序。

具体角色

  1. 初始事件分发器(Initialization Dispatcher)

  2. 同步(多路)事件分离器(Synchronous Event Demultiplexer)

  3. 系统处理程序(Handles)

  4. 事件处理器(Event Handler)

 

 

多路复用函数

在多路复用中,涉及到了 select,poll,epoll 函数。因此本质上都是同步I/O。

 

select

 

poll

 

epoll

 

  • 7
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值