5种IO模型的介绍

IO是Input/Output的缩写,涉及数据在计算机、设备和文件之间的传输。在Linux中,用户进程通过系统调用进行IO操作,通常包括等待数据和复制数据两个阶段。网络I/O主要讨论了从网卡到内核再到用户进程的数据流动。文章介绍了五种I/O模型:阻塞I/O、非阻塞I/O、多路复用I/O(如select)、信号驱动I/O和异步I/O,其中前四种属于同步I/O,而异步I/O在两个阶段都不阻塞进程。
摘要由CSDN通过智能技术生成

什么是IO?

IO 是 Input/Output 的缩写,指的是输⼊和输出。在计算机当中,IO 操作通常指将数据从⼀个设备或文件中读取到计算机内存中,或将内存中的数据写⼊设备或文件中。这些设备可以包括硬盘驱动器、网卡、键盘、屏幕等。
通常⽤户进程中的⼀个完整I/O分为两个阶段:
        ⽤户进程空间→内核空间
        内核空间→设备空间
I/O分为内存I/O、⽹络I/O和磁盘I/O三种,我们主要介绍网络IO
IO操作的两个阶段
Linux中进程⽆法直接操作I/O设备,其必须通过系统调⽤请求内核来协助完成I/O操作。
内核会为每个I/O设备维护⼀个缓冲区。
对于⼀个输⼊操作来说,进程I/O系统调⽤后,内核会先看缓冲区中有没有相应的缓存数据,没有的话再到设备(⽐如⽹卡设备)中读取(因为设备I/O⼀般速度较慢,需要等待);内核缓冲区有数据则直接复制到⽤户进程空间。所以,对于⼀个⽹络输⼊操作通常包括两个不同阶段:
1. 等待⽹络数据到达⽹卡,把数据从⽹卡读取到内核缓冲区,准备好数据。
2. 从内核缓冲区复制数据到⽤户进程空间。
⽹络I/O的本质是对socket的读取,socket在Linux系统中被抽象为流,I/O可以理解为对流的操
作。
⽹络I/O的模型可分为两种:
异步I/O(asynchronous I/O)
同步I/O(synchronous I/O)
同步I/O⼜包括
阻塞I/O(blocking I/O)
⾮阻塞I/O(non-blocking I/O)
多路复⽤I/O(multiplexing I/O)
信号驱动I/O(signal-driven I/O)
强调⼀下:信号驱动I/O属于同步I/O,原因往后看。
信号驱动I/O和异步I/O只作概念性的讲解,不作为学习重点。

五种I/O模型

阻塞I/O(blocking I/O)

对于⼀个套接字上的输⼊操作,第⼀步通常涉及等待数据从⽹络中到达,当所有等待分组到达时,它被复制到内核中的某个缓冲区。第⼆步是把数据从内核缓冲区复制到应⽤程序缓冲区。
同步阻塞I/O模型是最常⽤、最简单的模型。在Linux中,默认情况下,所有套接字都是阻塞的。下面我们以阻塞套接字的recvfrom的调用图来说明阻塞,如图所示:

 

非阻塞I/O(non-blocking I/O)

非阻塞的recvform 系统调⽤之后,进程并没有被阻塞,内核⻢上返回给进程,如果数据还没准备好,此时会返回⼀个 error EAGAIN EWOULDBLOCK )。
进程在返回之后,可以先处理其他的业务逻辑,稍后再发起recvform系统调⽤。
采⽤轮询的⽅式检查内核数据,直到数据准备好。再拷⻉数据到进程,进⾏数据处理。
在Linux下,可以通过设置套接字选项使其变为⾮阻塞。⾮阻塞的套接字的recvfrom操作如图所示:

 

可以看到前三次调⽤recvfrom请求时,并没有数据返回,内核返回 errno ( EWOULDBLOCK ),并不会阻塞进程。
当第四次调⽤recvfrom时,数据已经准备好了,于是将它从内核空间拷⻉到程序空间,处理数据。
在⾮阻塞状态下,I/O执⾏的等待阶段并不是完全阻塞的,但是第⼆个阶段依然处于⼀个阻塞状态(调用者将数据从内核拷⻉到⽤户空间,这个阶段阻塞)。

多路复用I/O(multiplexing I/O)

I/O多路复⽤的好处在于单个进程就可以同时处理多个⽹络连接的I/O。它的基本原理是不再由应⽤程序⾃⼰监视连接,⽽由内核替应⽤程序监视⽂件描述符。
以select函数为例,当⽤户进程调⽤了select,那么整个进程会被阻塞⽽同时,kernel会“监
视”所有select负责的socket,当任何⼀个socket中的数据准备好,select就会返回。
这个时候⽤户进程再调⽤read操作,将数据从内核拷⻉到⽤户进程,如下图所示:

 

信号驱动I/O(signal-driven I/O)

该模型允许socket进⾏信号驱动I/O,并注册⼀个信号处理函数,进程继续运⾏并不阻塞。当数据
准备好时,进程会收到⼀个SIGIO信号,可以在信号处理函数中调⽤I/O操作函数处理数据,如图
所示:

 

注意:虽然信号驱动IO在注册完信号处理函数以后,就可以做其他事情了。但是 第⼆阶段拷⻉数据的过程当中进程依然是被阻塞的 ,⽽后要介绍的异步IO是完全不会阻塞进程的,所以信号驱动虽然具有异步的特点,但依然属于同步IO。

异步I/O(asynchronous I/O)

相对于同步I/O,异步I/O不是按顺序执⾏。⽤户进程进⾏ aio_read 系统调⽤之后,就可以去处理其
他逻辑了,⽆论内核数据是否准备好,都会直接返回给⽤户进程,不会对进程造成阻塞。这是因为 aio _read 只向内核递交申请,并不关⼼有没有数据。等到数据准备好了,内核直接复制数据到进程空间,然后内核向进程发送通知,此时数据已经在⽤户空间了,可以对数据进⾏处理,如图所示:

 五种I/O模型⽐较

 

前四种I/O模型都是同步I/O操作,它们的区别在于第⼀阶段,⽽第⼆阶段是⼀样的:在数据从内核复制到应⽤缓冲区期间(⽤户空间),进程阻塞于recvfrom调⽤。
相反,异步I/O模型在等待数据和接收数据的这两个阶段都是⾮阻塞的,可以处理其他的逻辑,⽤户进程将整个I/O操作交由内核完成,内核完成后会发送通知。在此期间,⽤户进程不需要检查I/O操作的状态,也不需要主动拷⻉数据。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值