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

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

3天内不再提示

一文详细了解五种IO模型

GReq_mcu168 来源:噜噜呀​ 作者:噜噜呀​ 2022-02-14 14:38 次阅读

一、基本概念

五种IO模型包括:阻塞IO、非阻塞IO、IO多路复用、信号驱动IO、异步IO。

首先需要了解下系统调用的几个函数和基本概念。

1.1 简单介绍几个系统调用函数

由于我对于C语言不熟悉,几个系统函数参考了一些文章,如果错误欢迎指出!

recvfrom

Linux系统提供给用户用于接收网络IO的系统接口。从套接字上接收一个消息,可同时应用于面向连接和无连接的套接字。

如果此系统调用返回值<0,并且 errno为EWOULDBLOCK或EAGAIN(套接字已标记为非阻塞,而接收操作被阻塞或者接收超时 )时,连接正常,阻塞**接收数据(这很关键,前4种IO模型都设计此系统调用)。

select

select系统调用允许程序同时在多个底层文件描述符上,等待输入的到达或输出的完成。以数组形式存储文件描述符,64位机器默认2048个。当有数据准备好时,无法感知具体是哪个流OK了,所以需要一个一个的遍历,函数的时间复杂度为O(n)。

poll

以链表形式存储文件描述符,没有长度限制。本质与select相同,函数的时间复杂度也为O(n)。

epoll

是基于事件驱动的,如果某个流准备好了,会以事件通知,知道具体是哪个流,因此不需要遍历,函数的时间复杂度为O(1)。

sigaction

用于设置对信号的处理方式,也可检验对某信号的预设处理方式。Linux使用SIGIO信号来实现IO异步通知机制。

1.2 同步&异步

同步和异步是针对应用程序和内核交互而言的,也可理解为被被调用者(操作系统)的角度来说。

同步是用户进程触发IO操作并等待或轮询的去查看是否就绪,而异步是指用户进程触发IO操作以后便开始做自己的事情,而当IO操作已经完成的时候会得到IO完成的通知,需要CPU支持

1.3 阻塞&非阻塞

阻塞和非阻塞是针对于进程在访问数据的时候,也可理解为调用者(程序)角度来说。根据IO操作的就绪状态来采取的不同的方式。

阻塞方式下读取或写入方法将一直等待,而非阻塞方式下读取或写入方法会立即返回一个状态值。

下午撸代码饿了,好久没吃KFC了,决定去整个全家桶 ,这一切都要从一个全家桶说起~

我跑去肯德基买全家桶,但是很不巧,轮到我时,全家桶卖完了,我只能等着新做一份 …

二、阻塞IO模型

学习过操作系统的知识后,可以知道:不管是网络IO还是磁盘IO,对于读操作而言,都是等到网络的某个数据分组到达后/数据准备好后,将数据拷贝到内核空间的缓冲区中,再从内核空间拷贝到用户空间的缓冲区。

此时我已饥渴难耐,全程盯着后厨,等待着一分一秒(别多想 ),终于全家桶做好了,在此期间虽然什么事也没干,但是最后能吃到全家桶,我很幸福。

此处需要一个清新的脑回路,我就是程序,我想要全家桶,于是发起了系统调用,而后厨加工的过程就是在做数据准备和拷贝工作。全家桶最终到手,数据终于从内核空间拷贝到了用户空间。

简单看下执行流程:

一文详细了解五种IO模型

接下来发挥看图说话的专长了:阻塞IO的执行过程是进程进行系统调用,等待内核将数据准备好并复制到用户态缓冲区后,进程放弃使用CPU并一直阻塞在此,直到数据准备好。

三、非阻塞IO模型

此时我每隔5分钟询问全家桶好了没,在数次盘问后,终于出炉了。在每一次盘问之前,对于程序来说是非阻塞的,占用CPU资源,可以做其他事情。

每次应用程序询问内核是否有数据准备好。如果就绪,就进行拷贝操作;如果未就绪,就不阻塞程序,内核直接返回未就绪的返回值,等待用户程序下一个轮询。

一文详细了解五种IO模型

大致经历两个阶段:

等待数据阶段:未阻塞, 用户进程需要盲等,不停的去轮询内核。

数据复制阶段:阻塞,此时进行数据复制。

在这两个阶段中,用户进程只有在数据复制阶段被阻塞了,而等待数据阶段没有阻塞,但是用户进程需要盲等,不停地轮询内核,看数据是否准备好。

四、IO多路复用模型

排了很长的队,终于轮到我支付后,拿到了一张小票,上面有号次。当全家桶出炉后,会喊相应的号次来取。KFC营业员小姐姐打小票出号次的动作相当于操作系统多开了个线程,专门接收客户端的连接。我只关注叫到的是不是我的号,因此程序还需在服务端注册我想监听的事件类型。

多路复用一般都是用于网络IO,服务端与多个客户端的建立连接。下面是神奇的多路复用执行过程:

一文详细了解五种IO模型

相比于阻塞IO模型,多路复用只是多了一个select/poll/epoll函数。select函数会不断地轮询自己所负责的文件描述符/套接字的到达状态,当某个套接字就绪时,就对这个套接字进行处理。select负责轮询等待,recvfrom负责拷贝。当用户进程调用该select,select会监听所有注册好的IO,如果所有IO都没注册好,调用进程就阻塞。

对于客户端来说,一般感受不到阻塞,因为请求来了,可以用放到线程池里执行;但对于执行select的操作系统而言,是阻塞的,需要阻塞地等待某个套接字变为可读。

IO多路复用其实是阻塞在select,poll,epoll这类系统调用上的,复用的是执行select,poll,epoll的线程。

五、信号驱动IO模型

跑KFC嫌麻烦,刚好有个会员,直接点份外卖,美滋滋。当外卖送达时,会收到取餐电话(信号)。在收到取餐电话之前,我可以愉快地吃鸡或者学习。

当数据报准备好的时候,内核会向应用程序发送一个信号,进程对信号进行捕捉,并且调用信号处理函数来获取数据报。

一文详细了解五种IO模型

该模型也分为两个阶段:

数据准备阶段:未阻塞,当数据准备完成之后,会主动的通知用户进程数据已经准备完成,对用户进程做一个回调。

数据拷贝阶段:阻塞用户进程,等待数据拷贝。

六、异步IO模型此时科技的发展已经超乎想象了,外卖机器人将全家桶自动送达并转换成营养快速注入我的体内,同时还能得到口感的满足。注入结束后,机器人会提醒我注入完毕。在这个期间我可以放心大胆的玩,甚至注射的时候也不需要停下来!

类比一下,就是用户进程发起系统调用后,立刻就可以开始去做其他的事情,然后直到I/O数据准备好并复制完成后,内核会给用户进程发送通知,告诉用户进程操作已经完成了。

一文详细了解五种IO模型

特点:

异步I/O执行的两个阶段都不会阻塞读写操作,由内核完成。

完成后内核将数据放到指定的缓冲区,通知应用程序来取。

七、Java中的BIO,NIO,AIO操作系统的IO模型是底层基石,Java对于IO的操作其实就是进一步的封装。适配一些系统调用方法,让我们玩地更爽。

BIO,NIO,AIO涉及相关实操代码已收录至我的github,欢迎star~

7.1 BIO--同步阻塞的编程方式

JDK1.4之前常用的编程方式。

实现过程:

首先在服务端启动一个ServerSocket来监听网络请求,客户端启动Socket发起网络请求,默认情况下ServerSocket会建立一个线程来处理此请求,如果服务端没有线程可用,客户端则会阻塞等待或遭到拒绝,并发效率比较低。

服务器实现的模式是一个连接一个线程,若有客户端有连接请求服务端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销。当然,也可以通过线程池机制改善。

使用场景:

BIO适用于连接数目比较小且固定的架构,对服务器资源要求高,并发局限于应用中。

7.2 NIO--同步非阻塞的编程方式

7.2.1 NIO简介

NIO 本身是基于事件驱动思想来完成的,当 socket 有流可读或可写入时,操作系统会相应地通知应用程序进行处理,应用再将流读取到缓冲区或写入操作系统。一个有效的请求对应一个线程,当连接没有数据时,是没有工作线程来处理的。

服务器实现模式为一个请求一个通道,即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有 I/O 请求时才启动一个线程进行处

使用场景:

NIO 方式适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,并发局限于应用中,编程复杂,JDK1.4 开始支持。

7.2.2 NIO中的几种重要角色

有缓冲区Buffer,通道Channel,多路复用器Selector。

7.2.2.1 Buffer

在NIO库中,所有数据都是用缓冲区(用户空间缓冲区)处理的。在读取数据时,它是直接读到缓冲区中的;在写入数据时,也是写入到缓冲区中。任何时候访问NIO中的数据,都是通过缓冲区进行操作。

缓冲区实际上是一个数组,并提供了对数据的结构化访问以及维护读写位置等信息

Buffer的应用固定逻辑

相关的代码我会更新至github~

写操作顺序

clear()

put() -> 写操作

flip() ->重置游标

SocketChannel.write(buffer); ->将缓存数据发送到网络的另一端

clear()

读操作顺序

clear()

SocketChannel.read(buffer); ->从网络中读取数据

buffer.flip()

buffer.get() ->读取数据

buffer.clear()

7.2.2.2 Channel

nio中对数据的读取和写入要通过Channel,它就像水管一样,是一个通道。通道不同于流的地方就是通道是双向的,可以用于读、写和同时读写操作。

7.2.2.3 Selector

多路复用器,用于注册通道。客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求时才启动一个线程进行处理

7.3 AIO--异步非阻塞编程方式

进行读写操作时,只须直接调用api的read或write方法即可。一个有效请求对应一个线程,客户端的IO请求都是OS先完成了再通知服务器应用去启动线程进行处理。

使用场景

AIO方式使用于连接数目多且连接比较长(重操作)的架构,比如相册服务器,充分调用OS参与并发操作,编程比较复杂,JDK1.7开始支持。

八、总结从效率上来说,可以简单理解为阻塞IO<非阻塞IO<多路复用IO<信号驱动IO<异步IO。从同步和异步来说,只有异步IO模型是异步的,其他均为同步。

原文标题:一口气说出5种IO模型的

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

审核编辑:汤梓红

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

    关注

    87

    文章

    10994

    浏览量

    206767
  • C语言
    +关注

    关注

    180

    文章

    7534

    浏览量

    128899
  • 函数
    +关注

    关注

    3

    文章

    3911

    浏览量

    61313

原文标题:一口气说出5种IO模型的

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

收藏 人收藏

    评论

    相关推荐

    带你了解PWM原理、频率与占空比

    只能输出高电平和低电平,假设高电平为5V 低电平则为0V 那么我们要输出不同的模拟电压,就要用到PWM,通过改变IO口输出的方波的占空比从而获得使用数字信号模拟成的模拟电压信号。我们知道,电压是以一种
    发表于 03-27 14:12

    电机干货!了解电机的原理及分类

    了解电机的原理及分类 电机是传动及控制系统中的重要部分,目前电机应用的重点也从过去简单的传动向电机的速度、位置、转矩的精确控制转移; 电机为何能够转动?电机又有哪些分类?不同工作环境下需要选用
    发表于 03-12 09:35

    带你了解FPGA直方图操作

    灰度变换等处理过程。 而FPGA对于直方图处理主要分为以下三: 我们常见或者听说的直方图概念主要指直方图均衡,这也是最简单的一种方式,常见某些入门级的图像处理书籍或者文章。直方图规定化和直方图拉伸我们
    发表于 01-10 15:07

    带您一起详细了解IEEE802.3bt(PoE++)的有关特点

    Hqst华强盛(盈盛电子)导读:带您一起详细了解IEEE802.3bt(PoE++)的有关特点,让我们对IEEE802.3bt(PoE++)协议有更具体的了解
    的头像 发表于 01-04 11:26 639次阅读
    带您一起<b class='flag-5'>详细了解</b>IEEE802.3bt(PoE++)的有关特点

    【迪COF结构智能屏试用体验】基于串口通信的电子相册(动态平滑、完整代码)

    非常感谢迪的妍姐,给我提供了块COF智能屏测试,经过番摸索,详细了解了串口通讯的具体用法,结合上位机,试用Python脚本来进行通讯,实现了
    发表于 12-06 15:58

    人工智能大模型、应用场景、应用部署教程超详细资料

    人工智能是IC行业近几年的热词,目前此技术已经有很多成熟的模型和落地案例。在此跟大家做个分享,更多详细资料,请自行搜索:【展锐坦克邦】,坦克邦-智算天地集算法模型、部署说明于体,为广
    发表于 11-13 14:49

    详细了解什么是光纤涂覆机?

    光纤涂覆机的目的是:恢复被处理过的普通光纤或者保偏光纤、带状光纤等各类光纤的光纤涂层。 添加图片注释,不超过 140 字(可选) 光纤涂覆机的实现方式是:光纤涂覆机,主要作用是将裸露或者熔接厚的的光纤裸纤上涂覆一层光纤胶水,然后固化使其恢复或者增强原有的光纤物理特性和光学特性,全面替代热缩套管,使其不但具有一定的物理强度和弯曲特性,还能满足全反射等需求。 添加图片注释,不超过 140 字(可选) 光纤涂覆机的应用范围
    的头像 发表于 11-02 11:07 352次阅读
    <b class='flag-5'>详细了解</b>什么是光纤涂覆机?

    C51单片机的IO口介绍(下)

    上一篇文章我们对C51的IO简单的介绍了一下,现在我们来简单了解C51的IO的结构
    的头像 发表于 11-02 10:57 601次阅读
    C51单片机的<b class='flag-5'>IO</b>口介绍(下)

    详细了解超五类网线

    超五类网线是一种双绞线电缆,其中包括超五类非屏蔽双绞线(UTP—Unshielded Twisted Pair)和超五类屏蔽双绞线(STP)。这种网线在结构上由八根内芯和两两缠绕在一起的双绞线构成,具有更好的防止电流串扰的能力。 超五类网线可以用于千兆以太网中,传输距离可达100m,支持1000Mbps传输速度,满足了大多数人的使用需求,是目前国内应用最多的布线系统之一。与超五类网线相比,五类UTP网线的传输速率较低,传输距离也较短,但价格相对更亲民。 需要注
    的头像 发表于 10-20 10:24 1520次阅读

    多路IO复用模型和异步IO模型介绍

    多路 IO 复用模型 多路 IO 复用,有时也称为事件驱动 IO。它的基本原理就是有个函数会不断地轮询所负责的所有 socket ,当某个 socket有数据到达了,就通知用户进程。
    的头像 发表于 10-08 17:21 514次阅读
    多路<b class='flag-5'>IO</b>复用<b class='flag-5'>模型</b>和异步<b class='flag-5'>IO</b><b class='flag-5'>模型</b>介绍

    网络IO模型:阻塞与非阻塞

    阻塞 IO 模型 在Linux ,默认情况下所有的 socket 都是阻塞的,一个典型的读操作流程如图所示。 阻塞和非阻塞的概念描述的是用户线程调用内核 IO 操作的方式:阻塞是指 IO
    的头像 发表于 10-08 17:16 491次阅读
    网络<b class='flag-5'>IO</b><b class='flag-5'>模型</b>:阻塞与非阻塞

    IO如何实现

    IO模型 我们的程序基本上都是对数据的IO操作以及基于CPU的运算。 基于Java的开发大部分是网络相关的编程,不管是基于如Tomcat般的Web容器,或是基于Netty开发的应用间的RPC服务
    的头像 发表于 09-25 10:57 514次阅读
    <b class='flag-5'>IO</b>如何实现

    详细了解岩土工程安全监测的振弦采集仪

    详细了解岩土工程安全监测的振弦采集仪 岩土工程安全监测是工程建设过程中非常重要的一环,它可以及时发现和解决岩土工程中的问题,确保工程的安全和稳定。而振弦采集仪作为现代化的监测设备,被广泛应用于岩土
    的头像 发表于 07-11 11:23 288次阅读
    <b class='flag-5'>详细了解</b>岩土工程安全监测的振弦采集仪

    基石DDPM(模型架构篇),最详细的DDPM架构图解

    DDPM(模型架构篇):也就是本篇文章。在阅读源码的基础上,本文绘制了详细的DDPM模型架构图,同时附上关于模型运作流程的详细解说。本文不涉
    的头像 发表于 06-29 16:32 6516次阅读
    基石DDPM(<b class='flag-5'>模型</b>架构篇),最<b class='flag-5'>详细</b>的DDPM架构图解

    Linux驱动学习笔记:异步IO

    前几篇介绍了几种IO模型,今天介绍另一种IO模型——异步IO
    发表于 06-12 16:24 481次阅读