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;
}
相关推荐
数智工坊7 分钟前
UECP:不确定性增强的协同感知 | 基于物理先验的BEV融合新范式
linux·ubuntu·3d·机器人
xixiaoyunya2 小时前
移动办公场景下手机远程访问内网设备的技术方案选型与实践
网络·智能手机·智能路由器
ltl9 小时前
内核追踪:ftrace、kprobe、uprobe、tracepoint 生产实战
linux
·薯条大王9 小时前
经济实惠玩云服务器|一台云服务器多人共用,子账号配置教程
java·linux·运维·服务器·汇编·c++·python
weixin_4462608512 小时前
从被动镜像到主动智能体:面向网络物理人工智能的整体论数字孪生(HDT-Net)
网络·人工智能
ZJH__GO12 小时前
网络编程v4pro--实现聊天室文件传输功能
java·服务器·网络·计算机网络
小小、码农12 小时前
Linux进程控制:从fork到exec,手写一个简易Shell
linux·运维·服务器
不会就选b13 小时前
Linux之进程间通信(二)---模拟进程池
linux·运维·服务器
shengnan_wsn14 小时前
【协议】【TCP】
网络·网络协议·tcp/ip
烟雨江南78514 小时前
2026汽车制造与新能源整车柔性产线Agentic-Workflow白皮书:跨APS_MES_ERP多智能体动态排产与装配容错实战
大数据·网络·人工智能·自动化·ai客服·企业agent