0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Linux的5种IO模型

FPGA之家 来源:FPGA之家 作者:FPGA之家 2022-08-12 09:22 次阅读

哈喽,我是老吴,俺又来分享文章啦!

浑浑噩噩到了 30 岁,距离开滴滴还有 5 年的时间。

还有机会全身而退吗?

哈哈!

30 而立,今年会是值得拼搏的一年,干它!

以下是正文:

一、Linux 的 5 种 IO 模型
二、如何使用信号驱动式 I/O?
三、内核何时会发送 "IO 就绪" 信号?
四、最简单的示例
五、扩展知识

一、Linux 的 5 种 IO 模型

阻塞式 I/O:

系统调用可能因为无法立即完成而被操作系统挂起,直到等待的事件发生为止。

1ad5174c-19db-11ed-ba43-dac502259ad0.png

点击查看大图

非阻塞式 I/O (O_NONBLOCK):

系统调用则总是立即返回,而不管事件是否已经发生。

1ae66bb4-19db-11ed-ba43-dac502259ad0.png

点击查看大图

I/O 复用 (select、poll、epoll):

通过 I/O 复用函数向内核注册一组事件,内核通过 I/O 复用函数把其中就绪的事件通知给应用程序。

1af9df32-19db-11ed-ba43-dac502259ad0.png

点击查看大图

信号驱动式 I/O (SIGIO):

为一个目标文件描述符指定宿主进程,当文件描述符上有事件发生时,SIGIO 的信号处理函数将被触发,然后便可对目标文件描述符执行 I/O 操作。

1b1c96da-19db-11ed-ba43-dac502259ad0.png

点击查看大图

异步 I/O (POSIX 的 aio_ 系列函数):

异步 I/O 的读写操作总是立即返回,而不论 I/O 是否是阻塞的,真正的读写操作由内核接管。

1b327766-19db-11ed-ba43-dac502259ad0.png

点击查看大图

思考一下,什么时候应该选择何种 I/O 模型?为何要这么选择?

下面重点关注信号驱动式 I/O 这一模型,其他模型可查阅文末参考书籍。

二、如何使用信号驱动式 I/O?

一般通过如下 6 个步骤来使用信号驱动式 I/O 模型。

1> 为通知信号安装处理函数。

通过 sigaction() 来完成:

intsigaction(intsignum,conststructsigaction*act,structsigaction*oldact);

默认情况下,这个通知信号为 SIGIO。

2> 为文件描述符的设置属主。

通过 fcntl() 的 F_SETOWN 操作来完成:

fcntl(fd,F_SETOWN,pid)

属主是当文件描述符上可执行 I/O 时,会接收到通知信号的进程或进程组。

pid 为正整数时,代表了进程 ID 号。

pid 为负整数时,它的绝对值就代表了进程组 ID 号。

3> 使能非阻塞 I/O。

通过 fcntl() 的 F_SETFL 操作来完成:

flags=fcntl(fd,F_GETFL);
fcntl(fd,F_SETFL,flags|O_NONBLOCK);

4> 使能信号驱动 I/O。

通过 fcntl() 的 F_SETFL 操作来完成:

flags=fcntl(fd,F_GETFL);
fcntl(fd,F_SETFL,flags|O_ASYNC);

5> 进程等待 "IO 就绪" 信号的到来。

当 I/O 操作就绪时,内核会给进程发送一个信号,然后调用在第 1 步中安装好的信号处理函数。

6> 进程尽可能多地执行 I/O 操作。

循环执行 I/O 系统调用直到失败为止,此时错误码为 EAGAIN 或 EWOULDBLOCK。

原因:

信号驱动 I/O 提供的是边缘触发通知,即只有当 I/O 事件发生时我们才会收到通知,

且当文件描述符收到 I/O 事件通知时,并不知道要处理多少 I/O 数据。

三、内核何时会发送 "IO 就绪" 信号?

对于不同类型的文件描述符,情况不一样。

1> 终端

  • 对于终端,当有新的输入时会会产生信号。

2> 管道和 FIFO

对于读端,下列情况会产生信号:

  • 数据写入到管道中;
  • 管道的写端关闭;

对于写端,下列情况会产生信号:

  • 对管道的读操作增加了管道中的空余空间大小。
  • 管道的读端关闭;

3> 套接字

对于 UDP 套接字,下列情况会产生信号:

  • 数据报到达套接字;
  • 套接字上发生异步错误;

对于 TCP 套接字,信号驱动式 I/O 近乎无用。

  • 太多情况都会产生信号,而我们又无法得知事件类型,因此这里就不再列举其产生信号的情况。

四、最简单的示例

信号处理函数:

staticvolatilesig_atomic_tgotSigio=0;

staticvoidhandler(intsig)
{
gotSigio=1;
}

主程序:

intmain(intargc,char*argv[])
{
intflags,j,cnt;
structtermiosorigTermios;
charch;
structsigactionsa;
intdone;

/*Establishhandler*/
sigemptyset(&sa.sa_mask);
sa.sa_flags=SA_RESTART;
sa.sa_handler=handler;
if(sigaction(SIGIO,&sa,NULL)==-1){
perror("sigaction()
");
exit(1);
}

/*Setownerprocess*/
if(fcntl(STDIN_FILENO,F_SETOWN,getpid())==-1){
perror("fcntl()/F_SETOWN
");
exit(1);
}

/*Enable"I/Opossible"signalingandmakeI/Ononblocking*/
flags=fcntl(STDIN_FILENO,F_GETFL);
if(fcntl(STDIN_FILENO,F_SETFL,flags|O_ASYNC|O_NONBLOCK)==-1){
perror("fcntl()/F_SETFL
");
exit(1);
}

for(done=0,cnt=0;!done;cnt++){
sleep(1);

if(gotSigio){
gotSigio=0;

/*Readallavailableinputuntilerror(probablyEAGAIN)
orEOF*/
while(read(STDIN_FILENO,&ch,1)>0&&!done){
printf("cnt=%d;read%c
",cnt,ch);
done=ch=='#';
}
}
}
exit(0);
}

运行效果:

./build/sigio
a
cnt=0;reada
cnt=0;read

abc
cnt=4;reada
cnt=4;readb
cnt=4;readc
cnt=4;read

#
cnt=7;read#

该程序会先使能信号驱动 IO,然后循环执行计数操作。

当有 IO 就绪信号到来时,会去终端读取数据并打印出来,然后继续执行计数操作。

五、扩展知识

I/O 多路复用 、信号驱动 I/O 以及 epoll 机制可用于监视多个文件描述符。

它们并不实际执行 I/O 操作,当某个文件描述符处于就绪态,仍需采用传统的 I/O 系统调用来完成 I/O 操作。

相比 I/O 多路复用,当监视大量的文件描述符时信号驱动 I/O 有着显著的性能优势,原因是内核能够帮进程记录了正在监视的文件描述符列表。

信号驱动 I/O 的缺点:

  • 信号的处理流程较为复杂;

  • 无法指定需要监控的事件类型。

Linux 特有的 epoll 是一个更好的选择。

六、相关参考

UNIX 网络编程卷1

  • 6.2 I/O模型
  • 25 信号驱动式I/O

Linux-UNIX 系统编程手册

  • 63 其他备选的I/O模型

Linux 高性能服务器编程

  • 8.3 I/O 模型

Linux 多线程服务端编程_使用muduo C++网络库

  • 7.4.1 muduo的IO模型

审核编辑 :李倩



声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • Linux
    +关注

    关注

    87

    文章

    11238

    浏览量

    209043
  • 信号处理
    +关注

    关注

    48

    文章

    1009

    浏览量

    103217
  • 函数
    +关注

    关注

    3

    文章

    4318

    浏览量

    62488

原文标题:思考技术,也思考人生

文章出处:【微信号:zhuyandz,微信公众号:FPGA之家】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    一文解读Linux 5IO模型

    Linux里有五IO模型:阻塞IO、非阻塞IO、多路复用I
    的头像 发表于 11-09 11:12 250次阅读
    一文解读<b class='flag-5'>Linux</b> <b class='flag-5'>5</b><b class='flag-5'>种</b><b class='flag-5'>IO</b><b class='flag-5'>模型</b>

    Linux--IO多路复用(select,poll,epoll)

    IO多路复用——select,poll,epollIO多路复用是一操作系统技术,旨在提高系统处理多个输入输出操作的性能和资源利用率。与传统的多线程或多进程模型相比,IO多路复用避免了
    的头像 发表于 11-06 16:13 192次阅读

    华纳云监视Linux磁盘IO性能命令:iotop,iostat,vmstat,atop,dstat,ioping

    以下介绍6个监视 Linux 磁盘IO性能的命令(工具),它们分别是iotop、iostat、vmstat、atop、dstat、ioping,以下将附上简单的使用方法。 前言 磁盘IO
    的头像 发表于 10-24 14:43 133次阅读

    本地IO与远程IO:揭秘工业自动化中的两大关键角色

    在工业自动化领域,IO(Input/Output,输入/输出)模块扮演着至关重要的角色。它们作为连接控制系统与现场设备的桥梁,负责数据的采集与指令的执行。然而,随着技术的不断进步,IO模块也分为本地IO和远程
    的头像 发表于 10-08 18:06 318次阅读

    linux驱动程序如何加载进内核

    ,需要了解Linux内核的基本概念和API。以下是一些关键概念: 1.1 内核模块:Linux内核模块是一动态加载和卸载的代码,可以在不重新启动系统的情况下加载和卸载。驱动程序通常以内核模块的形式实现。 1.2 设备
    的头像 发表于 08-30 15:02 396次阅读

    Linux磁盘IO详细解析

      在讲解磁盘IO前,先简单说下什么是磁盘。磁盘是可以持久化存储的设备,根据存储介质的不同,常见磁盘可以分为两类:机械磁盘和固态磁盘。
    的头像 发表于 08-05 15:49 579次阅读
    <b class='flag-5'>Linux</b>磁盘<b class='flag-5'>IO</b>详细解析

    一体式IO与分布式IO:工业控制系统的两架构

    受到青睐。然而,一体式IO架构在小型系统中仍然有着广泛的应用。了解这两架构的特点和区别,有助于工程师和决策者为企业选择最合适的工业控制系统解决方案。
    的头像 发表于 07-17 16:12 924次阅读
    一体式<b class='flag-5'>IO</b>与分布式<b class='flag-5'>IO</b>:工业控制系统的两<b class='flag-5'>种</b>架构

    远程IO与分布式IO的区别

    在工业自动化和控制系统设计中,远程IO(Input/Output)和分布式IO是两个重要的概念。它们各自具有独特的特点和优势,适用于不同的应用场景。本文将详细探讨远程IO与分布式IO
    的头像 发表于 06-15 15:57 2381次阅读

    物理内存模型的演变

    内存管理概述中,主要是以Linux v2.6.11为例进行分析的,但是计算技术在不断发展,新的存储架构、新的指令集架构、新的SoC架构等都对物理内存模型的抽象提出了更高要求。为此,必须抽象一完全独立于硬件架构的物理内存
    的头像 发表于 02-25 10:35 446次阅读

    苹果正测试四AI模型支持自己的人工智能

    据报道,苹果正在测试四AI模型以支持其人工智能技术。这些模型可能包括苹果自家开发的“Ajax”,以及来自OpenAI和谷歌的两个外部大模型,分别是OpenAIGPT和Flan-T
    的头像 发表于 02-04 11:17 876次阅读

    EtherCAT IO的接线方法和流程是怎样的?

    EtherCAT IO的接线方法和流程是怎样的? EtherCAT是一用于实时以太网通信的开放式通信协议,具有低延迟和高带宽的优势。 EtherCAT IO是EtherCAT网络中连接到IO
    的头像 发表于 02-02 16:57 1921次阅读

    嵌入式Linux开发的三方式

    嵌入式Linux开发主要有三方式:裸机开发、SDK开发和驱动开发。
    的头像 发表于 01-22 14:22 940次阅读

    什么是io多路复用?IO多路复用的优缺点

    IO多路复用是一同步IO模型,它允许单个进程/线程同时处理多个IO请求。具体来说,一个进程/线程可以监视多个文件句柄,一旦某个文件句柄就绪
    的头像 发表于 01-18 15:48 1606次阅读

    请问ADUCM361 IO口兼容5V吗?

    请问:ADUCM361 IO口兼容5V吗?ADUCM361IO引脚模拟IIC 与一个5V传感器的IIC通信,IIC线上加5v上拉电阻,长时间
    发表于 01-11 06:01

    【爱芯派 Pro 开发板试用体验】部署爱芯派官方YOLOV5模型

    继上文开箱后,本文主要依托爱芯元智官方的实例,进行官方YOLOV5模型的部署和测试。 一、环境搭建 由于8核A55的SoC,加上目前Debian OS的工具齐全,所以决定直接在板上编译程序
    发表于 12-12 22:58