Linux五种IO模型与非阻塞IO

1.五种IO模型

IO 分为读和写,所有 IO 操作统一包含两个核心步骤:等待 IO 事件就绪 + 数据拷贝。读 IO 与写 IO 整体流程框架一致,但数据流向和就绪判定条件不同。IO 模型共有五种,分别为:

  1. 阻塞 IO
  2. 非阻塞 IO
  3. 信号驱动 IO
  4. IO 多路复用(select/poll/epoll)
  5. 异步 IO

1.1同步通信 vs 异步通信

同步和异步关注的是消息通信与 IO 数据处理机制。所谓同步,就是在发出一个调用时,在没有得到最终结果之前,该调用不会返回;一旦调用返回,就已经拿到了结果。简言之:由调用者主动等待调用结果,主动参与数据拷贝过程。异步则相反,调用发出之后会立即直接返回,无需等待结果;后续由被调用者通过状态通知、信号或回调函数,主动把处理结果告知调用者,内核全权完成等待就绪和数据拷贝,无需进程参与。

另外,回忆多进程多线程中的同步和互斥,这里网络 IO 的同步异步通信,和进程线程间的同步制约,是完全不相干的概念。进程 / 线程同步:是进程、线程之间的直接制约关系。指为完成某一任务的多个线程,需要在关键位置协调执行次序、相互等待或传递信息产生的制约关系,常用于保护临界资源的安全访问。

后续看到 "同步" 一词,一定要先区分场景:是 IO 通信层面的同步,还是进程线程同步互斥层面的同步。

1.2阻塞 vs 非阻塞

阻塞和非阻塞关注的是程序在等待调用结果(消息、返回值)时的线程状态。阻塞调用:调用结果返回前,当前线程会被挂起,让出 CPU,直到拿到结果后才返回继续执行。非阻塞调用:无法立刻获取结果时,调用也会立即返回,不会挂起当前线程,程序可以继续执行其他业务逻辑。

1.3非阻塞IO

非阻塞 IO 顾名思义,在 IO 事件没有就绪的时候不阻塞等待,而是立即返回,进程可以去处理其他事情。实现非阻塞可以使用 fcntl 函数,一个文件描述符默认是阻塞 IO,fcntl 函数原型为:int fcntl (int fd,int cmd,...);

fcntl 函数有 5 种功能:复制一个现有的描述符 (cmd=F_DUPFD)。获得 / 设置文件描述符标记 (cmd=F_GETFD 或 F_SETFD)。获得 / 设置文件状态标记 (cmd=F_GETFL 或 F_SETFL)。获得 / 设置异步 I/O 所有权 (cmd=F_GETOWN 或 F_SETOWN)。获得 / 设置记录锁 (cmd=F_GETLK,F_SETLK 或 F_SETLKW)。

设置文件描述符为非阻塞模式,需要使用 F_GETFL 和 F_SETFL 这两个命令组合完成,不能直接单独设置,核心步骤为先用 F_GETFL 获取原有文件状态标记,再通过按位或操作添加 O_NONBLOCK 非阻塞标记,最后用 F_SETFL 将新标记设置回去,保留原有属性不被覆盖。

cpp 复制代码
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>

// 设置文件描述符fd为非阻塞模式
int set_nonblock(int fd)
{
    // 1. 获取文件原有的状态标记
    int old_flag = fcntl(fd, F_GETFL);
    if (old_flag == -1)
        return -1;

    // 2. 添加非阻塞标记,保留原有属性
    int new_flag = old_flag | O_NONBLOCK;

    // 3. 设置新的状态标记
    int ret = fcntl(fd, F_SETFL, new_flag);
    if (ret == -1)
        return -1;

    return 0;
}
相关推荐
上海锝秉工控3 分钟前
省线型增量编码器:用“减法思维“重构工业控制的未来
网络·人工智能·重构
C语言小火车15 分钟前
嵌入式Linux应用开发技术栈完全指南
linux·运维·服务器
IT WorryFree25 分钟前
FortiGate 排错常用OID速查表(含Trap OID+轮询OID)
运维·网络
m0_7381207225 分钟前
渗透测试基础——基于Docker的Rsync服务靶场搭建与原理讲解
运维·服务器·网络·安全·web安全·docker·容器
CoreTK芯通康EMC整改41 分钟前
PCB 信号回流路径 EMC 失效深度解析:原理、误区与量产级整改方案
网络·经验分享·安全·emc整改案例·emc整改
asdfg125896344 分钟前
运营商的路由器到路由器之间是如何传输的
网络·智能路由器
代码中介商1 小时前
HTTP进化史:从1.0到3.0的核心变革
网络·网络协议·http
ZStack开发者社区1 小时前
ZSTACK · 答客问 | 什么时候该升级,什么时候再等等
网络·云计算
MXsoft6181 小时前
**混合云统一监控实践:私有云+公有云的一体化运维方案**
运维·网络·数据库
天南散修1 小时前
MT7916驱动中802.11转换为802.3
linux·网络·驱动开发·wifi·802.11