写点什么

IO 模型

用户头像
无心
关注
发布于: 2021 年 03 月 21 日

内核空间与用户空间

操作系统的核心是内核,可以系统受访问受保护的内存,也有访问底层物理设备的权限,为了保护内核安全,避免用户进程直接操作系统内核,操作系统将虚拟内存分为内核空间和用户空间;

用户空间不能直接访问内核空间,也不能调用内核函数,需要发起系统调用,从用户态切换到内核态;

同步与异步, 阻塞与非阻塞

阻塞与非阻塞主要是从调用者等待返回结果等角度看;

同步与异步是从被调用者处理请求的方式看问题,比如先返回,后台再处理,处理完成再回调通知给调用者结果,这就是异步;

一台机器应用 A 到另一台 B 机器应用 B,数据是怎么传输的?

(1) A 数据从进程用户空间到操作系统内核

(2) 数据从内核空间 DMA 拷到网卡

(3) 网卡通过网线将数据发到交换机等物理设备,最后到 B 机器的网卡

(4) B 机器从网卡将数据 DMA 拷贝到操作系统内核

(5) 数据从内核到进程用户空间


IO 模型

举个例子,读数据分为两步:

(1) 数据准备(等待数据到达)

(2) 将准备好的数据,拷贝到内核空间,再从内核空间拷贝到用户进程空间

1. 阻塞式 I/O

Blocking I/O;

发起 recvfrom 系统调用,在返回数据前,一直阻塞

2. 非阻塞式 I/O

Non-Blocking I/O;

配置 socket 为 Non-Blocking 模式后,发起 recvfrom 系统调用,就绪,在数据未就绪前,会返回 EWOULDBLOCKING;

这种模式大量消耗 CPU

3. IO Multiplexing

NIO, IO 多路复用, 事件驱动; 需要 select、poll、epoll(linux)来配合;

将数据准备和数据拷贝两个过程分离,select 负责弹出数据准备好的 socket,recvfrom 负责数据拷贝;

多个 socket 注册到一个 selector 上,主线程循环调用 selector.select 方法,如果没有任何 socket 有事件就绪,则阻塞;有就绪事件,就处理就绪事件;

优点是一个线程可以监听多个 socket 的事件,并且只有在存在就绪事件时,才会使用 IO 资源

4. Signal-Driven I/O

信号驱动 I/O;

用户线程发起一个 IO 请求,会给对应 socket 注册一个信号函数,用户线程继续执行,内核有准备就绪的数据时,会通知回调函数,然后发起 recvfrom 系统调用,拷贝数据到用户空间,用户执行读写事件处理;

5. AIO

异步 I/O;

发起 aio_read 系统调用,通知内核,直接返回,内核会异步处理数据(包括等待数据准备好,将数据拷贝到用户空间);

优点是全程异步,操作全部托管内核处理;

缺点是无法一次读取更多准备好的数据;


用户头像

无心

关注

8年+ java 开发经验 2019.02.13 加入

原来过得很快乐

评论

发布
暂无评论
IO 模型