IO模型详解(学习总结)

437 阅读3分钟

IO过程

  • IO调用请求

用户进程向操作系统发起IO调用请求

  • 数据准备阶段(DMA拷贝)

操作系统准备数据(DMA设备代替了CPU进行拷贝),把IO外部设备的数据,加载到内核缓冲区

  • 数据复制阶段 (CPU拷贝)

操作系统拷贝数据,将内核缓存区的数据(DMA缓冲区)拷贝到用户进程缓冲区(CPU拷贝)

BIO 阻塞模型

IO请求,数据准备阶段和数据复制阶段都是同步阻塞

NIO 非阻塞模型

  • 数据准备阶段——同步非阻塞

频繁的通过用户进程发起数据状态询问,引入用户态和内核态的状态切换

  • 数据复制阶段——同步阻塞

数据复制阶段占用CPU资源,从内核缓冲区复制到用户空间

IO多路复用模型(JAVA NIO)(异步阻塞IO模型)

不再通过用户进程发起多次数据状态询问,而是调用一次内核函数,让内核去遍历询问,减少了内核切换

select、poll和epoll区别

selectpollepoll
底层数据结构数组链表红黑树和双链表
获取就绪的fd遍历遍历事件回调
事件复杂度O(n)O(n)O(1)
最大连接数1024无限制无限制
fd数据拷贝每次调用select,需要将fd数据从用户空间拷贝到内核空间每次调用poll,需要将fd数据从用户空间拷贝到内核空间使用内存映射(mmap),不需要从用户空间频繁拷贝fd数据到内核空间

什么是IO多路复用_IO多路复用同步异步阻塞和非阻塞

图5 IO多路复用

如图5所示,通过Reactor的方式,可以将用户线程轮询IO操作状态的工作统一交给handle_events事件循环进行处理。用户线程注册事件处理器之后可以继续执行做其他的工作(异步),而Reactor线程负责调用内核的select函数检查socket状态。当有socket被激活时,则通知相应的用户线程(或执行用户线程的回调函数),执行handle_event进行数据读取、处理的工作。由于select函数是阻塞的,因此多路IO复用模型也被称为异步阻塞IO模型。注意,这里的所说的阻塞是指select函数执行时线程被阻塞,而不是指socket。一般在使用IO多路复用模型时,socket都是设置为NONBLOCK的,不过这并不会产生影响,因为用户发起IO请求时,数据已经到达了,用户线程一定不会被阻塞。

信号驱动模型

  • 数据准备阶段——异步非阻塞

数据准备好之后,通过信号通知用户进程

  • 数据拷贝阶段——同步阻塞

数据准备好之后的拷贝过程,还是同步阻塞

AIO异步IO模型

用户进程发起IO调用请求后,数据准备以及数据拷贝全部完成后,通知用户进行。完全异步非阻塞

参考

看一遍就理解:IO模型详解