非阻塞式 I/O

概述

非阻塞式 I/O, 相对复杂, 增加了很繁琐的输入输出缓冲区, 通常讲解此类 I/O 会用下面这张图来描述, 对于非阻塞式的涉及来说, 光这一张图的讲解太过敷衍.

非阻塞式 I/O IO

先大致描述以下这张图, 进程调用 recvfrom 方法, 向内核获取 I/O 数据(也就是输入输出, 缓冲流的数据), 如果内核有数据, 则复制数据并返回结果, 如果没有, 则返回 BWOULDBLOCK 标志(不同系统标志不尽相同). 仅单纯的使用非阻塞式系统调用, 性能不会太好, 需要有很多复杂的缓冲流维护.

相较于阻塞式 I/O

了解非阻塞式 I/O, 必然要对 阻塞式 I/O 的痛点有一定的了解.

  1. 当标准输入可读, 本进程便向标准输入索要数据, 并将得到的数据通过 writen 写入 sockfd 发送缓冲区(buf)中, 但是, 如果 sockfd 发送缓冲区已经被写满(网络过慢, 还来不及发送给服务器), 此时, 进程阻塞于 writen 操作.

  2. 当套接字缓冲区有数据可读, sockfd 可读, 进程将获取到的数据通过 write 写到准输出, 但是如果 write 操作的速度甚至慢于网络传输, 那么进程将阻塞于写操作, 无法顾及服务端新发送的数据.

由于以上两点原因, 我们可以将 io 操作拆的更细一点, 这里将从标准输入读, 写入套接字, 套接字读, 套接字写入标准输入四部分全部拆出来, 只要有任意一部分 I/O 就绪, 则执行. 为了监听套接字缓冲区是否占满或者是否为空, 我们需要在添加两个缓冲区分别缓冲套接字发送缓冲区和套接字接收缓冲区.

从标准输入到服务器的数据

从标准输入到服务器的数据

从套接字到标准输出的数据

非阻塞式 I/O 时间线


这里需要使用非阻塞式 I/O, 即尝试读写, 失败则跳过继续, 防止进程阻塞.

以上便实现了单进程的 I/O 复用且非阻塞式的套接字编程.

Hello world!
文章已创建 197

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部