提纲:
🔥Linux中的I/O
BIO:阻塞式I/O
NIO:非阻塞I/O
I/O多路复用
异步I/O
信号驱动 I/O🎈面试八股真题
- 1、简单讲讲I/O 多路复用
🔥Linux中的I/O
1. BIO:阻塞式I/O
-
两次阻塞
-
1、在内核等待数据拷贝至内核缓冲区,例如网络 I/O,数据往往不是立刻到达
-
2、在数据从内核缓冲区拷贝至用户进程缓冲区时阻塞
-
2.NIO:非阻塞I/O
-
当数据还没有拷贝至内核缓冲区时,系统会返回给用户进程一个错误信息,提示进程不要挂起,继续执行
-
NIO 解决了 BIO 第一次阻塞的问题,但进程其实仍然需要等待,用在单个进程的 I/O 上体现不出效果,在 I/O 多路复用中能体现出重要作用
3.I/O多路复用
-
类似于单 Reactor 模型,单个线程通过 select/epoll 指令,完成多个网络 I/O
-
原理:单个进程通过 select/epoll 对多个连接进行轮询,有连接数据准备完成,再调用 recvfrom进行读取
-
若连接数只有一个,I/O 多路复用还不如 BIO,因为调用了两次系统指令,但对于连接数较多情况,BIO 需要多线程处理不同连接数据,I/O 多路复用可以由一个线程来完成,且通常采用 NIO 的方式,即线程是被 select 阻塞,而不是被 I/O 阻塞,在一个 socket 没有准备就绪时,线程可以处理其他已经准备好的 socket
-
# Java 中使用 Selector 实现 I/O 多路复用,ByteBuffer 实现了零拷贝,即通过 mmap 的系统调用方式,将内核内存直接映射到进程的 vma 虚拟内存空间上,从而不需要进行第二次拷贝数据的阻塞
4.异步I/O
-
即线程发起 I/O 后,可以立刻执行其他操作,由内核去异步进行 I/O,当内核准备就绪后,通过信号通知线程,读取数据,异步 I/O 通常可以采用 Proactor 模型来实现,即一个 Proactor 专门负责接收数据,工作线程只需要负责处理并返回结果,
5.信号驱动 I/O
-
内核使用 signal 通知线程 I/O 完成
二、面试八股真题🎈🎈🎈
1、简单讲讲I/O 多路复用
目前支持I/O多路复用的系统调用有 select,pselect,poll,epoll,实际上他们都是同步I/O,读写过程是阻塞的。
- select