内核空间与用户空间
- 操作系统内核
可以访问受保护的内存空间,拥有访问底层硬件设备的所有权限。
为了保护内核的安全,操作系统将虚拟空间划分为:
- 内核空间(内核代码运行的地方)
- 用户空间(用户程序代码运行的地方)
内核空间和用户空间是隔离的。用户程序不能直接操作内核,需要通过系统调用来与内核进行通信。
socket的出入
https://blog.csdn.net/fen_liu/article/details/120410870
对于一个socket的出入操作,通常包括两个阶段:
- 等待数据从网络中到达(数据到达后,被复制到内核的缓冲区)
- 把数据从内核缓冲区复制到用户应用进程缓冲区
五种IO模型
阻塞式I/O
- 解释
当应用进程调用了recv()这个系统调用,操作系统就开始了IO的第一个阶段,用户这边,整个进程会被阻塞,当内核等到数据准备好了,将数据从内核拷贝到用户内存,然后内核返回结果,用户进程解除阻塞。
- 特点
在IO的两个阶段都阻塞;阻塞式不消耗CPU时间。
- 场景
阻塞 Socket、Java BIO。适用并发较小的网络应用,并发较大的不适用,因为一个请求 IO 阻塞进程,就要为每个请求分配一个进程(线程)来响应,开销大。
非阻塞式I/O
- 解释
当用户进程发出 recv() 操作时,如果内核中的数据还没有准备好,那么它并不会阻塞用户进程,而是立刻返回一个错误码。一旦内核中的数据准备好了,并且又再次收到了用户进程的系统调用,那么它马上就将数据拷贝到了用户内存,然后返回。
- 特点
在第二阶段阻塞;进程轮询调用(polling),消耗 CPU 资源。
- 场景
SOCKET 设置 NON BLOCKING 属性。支持并发量小,不用及时响应的网络应用。
IO多路复用(事件驱动)
- 解释
当用户进程调用了 select(poll、epoll),那么整个进程会被阻塞,而此时,内核会监视所有 select 负责的 socket,当任何一个 socket 中的数据准备好了,select 就会返回。这个时候用户进程再调用 recv 操作,将数据从内核拷贝到用户进程。
- 特点
第一阶段在select上阻塞,第二阶段依旧阻塞;性能好,Reactor模式。
- 场景
Java NIO,Nginx。适用高并发服务应用开发,一个进程/线程响应多个请求。
https://mp.weixin.qq.com/s/3gC-nUnFGv-eoSBsEdSZuA
https://cloud.tencent.com/developer/article/1586974
信号驱动式I/O
- 解释
应用进程使用 sigaction 系统调用,内核立即返回,应用进程可以继续执行,也就是说等待数据阶段应用进程是非阻塞的。内核在数据到达时向应用进程发送 SIGIO 信号,应用进程收到之后在信号处理程序中调用 recv()将数据从内核复制到应用进程中。
- 特点
特点:第二阶段阻塞;通知机制,不是轮训;CPU利用高于非阻塞式IO。
异步I/O
- 解释
应用进程执行 aio_read 系统调用会立即返回,应用进程可以继续执行,不会被阻塞,内核会在所有操作完成之后向应用进程发送信号。
- 特点
两个阶段都不会阻塞;异步 I/O 的信号是通知应用进程 I/O 完成,而信号驱动 I/O 的信号是通知应用进程可以开始 I/O。
- 场景
Java 7 AIO、高性能服务器,高性能高并发。