开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第5天,点击查看活动详情
常见 IO 模型
-
阻塞式I/O
-
非阻塞式I/O
-
I/O服用(select 和 poll)
-
信号驱动式I/O(SIGIO)
-
异步 I/O (POSIX 的 aio_ 系列函数)
阻塞式 I/O 模型
非阻塞式 I/O 模型如下图所示:
进程调用 recvfrom, 其系统调用直到数据报到达且被复制到引用进程的缓冲区中或者发生错误才返回。进程在调用 recvfrom 开始到它返回的争端时间内是被阻塞的。 recvfrom 成功返回后,应用进程开始处理数据报。
非阻塞式 I/O 模型
非阻塞式 I/O 模型如下图所示:
在前三次的 recvfrom 时没有数据可以返回,因此内核立即返回一个 EWOULDBLOCK 错误。当第四次调用 recvfrom 的时候有数据准备好,它立刻被复制到应用进程缓冲区中,recvfrom 成功返回。
当应用进程循环调用 recvfrom 时,称之为轮询(polling)。应用进程持续轮询内核,查看某个操作是否就绪,这样做会耗费大量的 CPU 时间。
I/O 复用模型 (select,poll)
I/O 复用(I/O multiplexing)模型如下图所示:
看上图可以得到,复用 I/O 模型比阻塞式 I/O 模型,多一些动作。因此,如果把复用 I/O 模型来做单系统调用,性能略微不如阻塞式 I/O 模型。
相比于阻塞式 I/O 模型,复用 I/O 模型的优势是能够等待多个描述符就绪(回忆下简单的tcpserver, tcpclient通信,每次read 只能等待一个socket,想要同时处理多个socket需要开多线程)。
信号驱动式 I/O 模型
信号驱动 I/O (signal-driven I/O)模型如下图所示:
我们为套接字开启信号驱动式 I/O 功能,并通过 sigaction 系统调用安装一个信号处理函数。该系统调用将立即返回,我们的进程继续工作,也就是说他没有被阻塞。当数据报准备好的时候,内核产生一个 SIGIO 信号。我们的进程接收到信号就可以调用 recvfrom 把数据从内核层拷贝到应用层。
异步 I/O 模型
异步 I/O (asynchronous)模型如下图所示:
一般异步 I/O 的工作机制是:告知内核启动某个动作,并让内核在整个操作(包括将数据从内核复制到我们自己的缓冲区)完成后通知我们。
总结
-
阻塞式 I/O 模型: 调用 recvfrom 后一直阻塞,直至数据完全准备好(1. 内核层接收到数据;2. 数据从内核层拷贝到用户层)。
-
非阻塞式 I/O 模型:调用 recvfrom 不断的查询(1. 内核是否接收到数据);满足条件后 recvfrom 获取数据(2. 数据从内核层拷贝到用户层)。
-
I/O 复用模型:与阻塞时 I/O 模型大致相同,阻塞在 select 处,数据准备好调用调用 recvfrom 接收数据。
-
信号驱动式 I/O 模型:为套接字开启信号驱动式 I/O 功能,当内核数据准备好发信号通知用户数据,用户调用 recvfrom 接收数据。
-
异步 I/O 模型: