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

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

3天内不再提示

只需要3分钟就能让你快速了解信号驱动式IO 快来看看吧

GReq_mcu168 来源:嵌入式Hacker 作者:吴伟东Jack 2021-03-18 11:50 次阅读

一、Linux 的 5 种 IO 模型

阻塞式 I/O:

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

非阻塞式 I/O (O_NONBLOCK):

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

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

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

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

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

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

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

思考一下,什么时候应该选择何种 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模型

编辑:jq

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

    关注

    12

    文章

    1798

    浏览量

    84929

原文标题:3 分钟快速了解信号驱动式 IO

文章出处:【微信号:mcu168,微信公众号:硬件攻城狮】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    增量编码器3大特点,工作模式,精度,输出脉冲信号 一起了解一下吗

    增量编码器3大特点,工作模式,精度,输出脉冲信号...一起了解一下吗?在现代工业自动化和控制系统中,增量编码器扮演着至关重要的角色。它可
    的头像 发表于 08-15 14:20 293次阅读
    增量<b class='flag-5'>式</b>编码器<b class='flag-5'>3</b>大特点,工作模式,精度,输出脉冲<b class='flag-5'>信号</b> 一起<b class='flag-5'>了解</b>一下吗

    为什么Hssl_MulitRead函数需要2个DMA通道,而Hssl_MulitWrite函数只需要1个DMA通道吗?

    有人能解释为什么 Hssl_MulitRead 函数需要 2 个 DMA 通道,而 Hssl_MulitWrite 函数只需要 1 个 DMA 通道吗?
    发表于 05-24 07:38

    使用带编码器三相电阻采样,三相都有参与运算但实际上输入信号只需要UV两相,为什么?

    如题,使用带编码器三相电阻采样,发现三相都有参与运算,但实际上输入信号只需要UV两相,W相输入数据不会影响电机运行效果,请问这是什么原因?出现电磁噪音比较大,有那些方法可以解决?如果都能解决,可以提供有偿服务。
    发表于 04-08 08:08

    勋瑞光电科技:高端显示器首选IPS面板?3分钟带你了解强大之处!

    在当今数字化生活中,显示器的选择对于我们的日常工作和娱乐至关重要。而当提到高端显示器,IPS(In-Plane Switching)屏幕往往备受推崇。 那么,为什么IPS屏幕如此受欢迎?它究竟有何独特之处?跟着勋瑞光电科技一起在3分钟内深入
    的头像 发表于 03-22 09:28 301次阅读

    3分钟快速实现串口PLC远程下载程序操作说明

    3分钟快速实现串口PLC远程下载程序操作说明 搜索蓝蜂物联网官网,即可免费领取样机使用!!先到先得!!! 一. 适用产品型号 其余型号网关此功能正在开发中,敬请期待。 二. 远程下载功能使用流程
    的头像 发表于 02-26 15:38 515次阅读
    <b class='flag-5'>3</b><b class='flag-5'>分钟</b><b class='flag-5'>快速</b>实现串口PLC远程下载程序操作说明

    分钟了解飞创直线电机运动模组特点、选型及应用-FCL系列

    分钟了解飞创直线电机运动模组特点、选型及应用-FCL系列
    的头像 发表于 02-05 16:28 467次阅读
    三<b class='flag-5'>分钟</b><b class='flag-5'>了解</b>飞创直线电机运动模组特点、选型及应用-FCL系列

    PEAK版本升级,看看有没有关注的新功能?

    近期PEAK进行了重要的版本升级,这次升级带来了许多令人兴奋的功能优化,助力您的工作流程更加便捷高效。为了帮助用户更好地了解PEAK新版本,我们提供了详细的说明和指导,快来看看有没有关注的新功能
    的头像 发表于 12-14 08:04 491次阅读
    PEAK版本升级,<b class='flag-5'>看看</b>有没有<b class='flag-5'>你</b>关注的新功能?

    AD9162通过SPI进行寄存器配置时,只需要配置sequence中的寄存器吗?

    对AD9162通过SPI进行寄存器配置时,只需要配置sequence中的寄存器吗?sequence外的其它寄存器就不用管了? sequence中有对寄存器的读,这些读操作可以不进行吗? 谢谢。
    发表于 12-11 06:36

    AD2S1210串行数据输出的CS信号或WR信号是不是只需要配置WR信号

    关于AD2S1210这款芯片的串行数据输出的CS信号或WR信号是不是只需要配置WR信号?CS信号直接拉到地可以吗?
    发表于 12-06 06:35

    越来越多的信号采用差分信号真的懂吗?

    可以想象,这两个导体上被同时加入的一个相等的电压,也就是所谓共模信号,对一个差放大系统来说是没有作用的,也就是说,尽管一个差分放大器的输入有效信号幅度只需要几毫伏,但它却可以对一个高
    的头像 发表于 11-29 17:34 639次阅读
    越来越多的<b class='flag-5'>信号</b>采用差分<b class='flag-5'>信号</b>,<b class='flag-5'>你</b>真的懂吗?

    还没使用SiC FET?快来看看本文,秒懂SiC FET性能和优势!

    还没使用SiC FET?快来看看本文,秒懂SiC FET性能和优势!
    的头像 发表于 11-29 16:49 566次阅读
    还没使用SiC FET?<b class='flag-5'>快来看看</b>本文,秒懂SiC FET性能和优势!

    信号驱动IO与异步IO的区别

    一. 谈信号驱动IO (对比异步IO来看) 信号驱动
    的头像 发表于 11-08 15:32 843次阅读
    <b class='flag-5'>信号</b><b class='flag-5'>驱动</b><b class='flag-5'>IO</b>与异步<b class='flag-5'>IO</b>的区别

    使用Python只需要3行语句就能剪辑音乐

    没看错,使用Python, 只需要3行语句就能剪辑音乐,比如我要剪辑《End of Time》33秒到110秒的音乐片段: 运行这个脚本
    的头像 发表于 10-31 11:31 434次阅读
    使用Python<b class='flag-5'>只需要</b><b class='flag-5'>3</b>行语句<b class='flag-5'>就能</b>剪辑音乐

    2分钟!带你搞清楚50欧姆的由来,快来看看吧

    电源欧姆
    安泰仪器维修
    发布于 :2023年10月13日 13:47:11

    2分钟!带你搞清楚50欧姆的由来,快来看看吧!#电路知识 #电工 #单片机

    电路单片机仪器仪表
    安泰仪器维修
    发布于 :2023年10月09日 10:27:30