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;
}
相关推荐
叼烟扛炮33 分钟前
[LangChain] 学习笔记(02):LCEL 链式调用与动态模型配置实战
服务器·开发语言·网络·笔记·学习·langchain
智慧光迅AINOPOL1 小时前
POF光电复合缆多业务承载原理
网络·安全·智能路由器
feng_you_ying_li1 小时前
linux之网络层
linux·运维·网络
步行cgn1 小时前
HTTP 请求报文结构详解:请求行、请求头、请求体各自的作用
网络·网络协议·http
未来之窗软件服务1 小时前
Linux 运维日志删除的多种方式—东方仙盟
linux·运维·服务器·仙盟创梦ide·东方仙盟
小雉系统2 小时前
BcoreOS实战:用一个升级包,让Rocky Linux跑进Debian服务器
linux·运维·服务器·debian
thethefighter2 小时前
快速预览Word、WPS秒开,支持空格弹窗
linux·word·wps·快速预览·空格弹窗·nhdeepview
一只小鱼儿吖2 小时前
内网穿透技术全景:原理、安全与实践
网络·安全
用户8351414049492 小时前
把日志和寄存器值喂给AI做故障定位,我的实际问法
linux·ubuntu
bj_bluewei_tech2 小时前
拯救者玩游戏掉帧卡顿,温度不高是什么原因?
网络·电脑·笔记本电脑·玩游戏