1. 同步阻塞式IO:需要等待数据到内核空间和用户空间的两次拷贝
  2. 同步非阻塞式IO:轮询数据到内核空间的拷贝情况,等待数据到用户空间的拷贝
  3. 异步IO:都不等待,数据到用户空间拷贝好了后通知

NIO的实现

IO多路复用个人认为是NIO的一种实现
IO信号驱动模型也是既有NIO但是同时也进行了改进

IO多路复用

  1. 解决思路:应用程序不去主动查询啦,而是让系统通知我,就是一个发布订阅的过程。
  2. select方式:有限制fd数组最多1024个
    1. 应用程序调用select,将监听的fd数组传入内核,进程阻塞
    2. 内核一旦发现数组中的某个fd(文件描述符)ok了,给这些fd打上标记所有的fd数组,
    3. 应用程序遍历返回的所有fd,依次将有已完成标记的文件复制到用户空间

image.png

  1. poll方式:过程和select类似,但是传的是一个链表,突破1024的限制
  2. epoll方式
    1. 应用程序通过epoll_ctl()注册一个监听fd到内核的fd红黑树中
    2. 当红黑树中的某个fd就绪时,会放入就绪链表中
    3. 应用程序调用epoll_wait()时便得到通知

image.png

个人感觉IO多路复用实际上就是NIO的一种实现方式 select/poll是轮询的一种fd数组和链表,每次给内核一组fd,内核返回有就绪的fd epoll:有点事件驱动的意思啦,就是有无事件时等待,有事件时触发通知

IO信号驱动模型

信号驱动IO不再用主动询问的方式去确认数据是否就绪,而是向内核发送一个信号(调用sigaction的时候建立一个SIGIO的信号),然后应用用户进程可以去做别的事,不用阻塞。当内核数据准备好后,再通过SIGIO信号通知应用进程,数据准备好后的可读状态。应用用户进程收到信号之后,立即调用recvfrom,去读取数据。
image.png

总结

IO模型 - 图4

参考资料