首页 > 编程知识 正文

excel基础入门教程,I/O设备

时间:2023-05-04 03:38:09 阅读:134526 作者:4525

首先,在开始学习netty之前,您需要先简单了解I/O知识。 netty的所有努力都基于操作系统对I/O的持续优化和Java对这些能力的持续支持,因此在开始学习netty之前,请务必先学习I/O的基础知识

概念解释I/O I/O : I/O是输入和输出的缩写,表示输入/输出。 根据操作对象,分为存储器I/O、磁盘I/O、网络I/O等。 在Unix和Linux操作系统上,所有组件都是一个文件,文件是流的外部表示形式。从这些流中读取数据,然后系统调用read函数,将这些流转换为一个系统有很多流,我们在操作时用文件描述符文件描述符唯一识别

同步和异步同步:同步和异步是今后讨论中经常遇到的两个词。 首先,我要明确说明这两个词的含义。 同步意味着从数据请求者启动请求到最后完成整个数据拷贝的过程必须由请求者自己完成。 异步是指数据请求方发出并回复请求命令,请求方处理数据后通知数据请求方,数据的等待和整个处理过程由请求方进行

阻塞和无阻塞,无阻塞:阻塞、无阻塞、同步和异步是从两种不同的角度描述事物的,没有直接的关联。 阻塞是指用户线程开始请求数据,系统内核中的数据未就绪时,如果当前用户线程等待系统内核就绪后返回,则为阻塞,当前用户线程立即返回

文件描述符文件描述符(File Descriptor ) :作为文件描述符的fd是非负整数,当打开现有文件或创建新文件时,内核返回文件描述符,为了读写文件,用fd进行读写

轮询:轮询的英译是轮询,是日常程序中常用的处理方式。 通过不断循环某个特定事件并根据事件返回结果,建立相应的处理逻辑。 轮询是不间断的每周重复,直到以某种手段强制中断该过程为止。 在Java中,所谓的死循环是最简单的轮询方式

典型的I/O模型块I/O模型【块I/O】块I/O模型是所有I/O模型中最简单、最容易理解的I/O模型。 整个过程采用线性处理方式。 即请求数据-等待数据准备-等待数据复制-数据复制完成并返回结果。 但是,对这种方法有非常大的确定。 整个过程

进程应用进程向系统内核发出请求,调用系统函数recvfrom读取数据

系统内核开始准备数据报,当前应用进程被阻止

系统将数据从内核空间复制到APP应用空间

复制数据完成后,recvfrom函数返回成功。

形象

了解非块I/O模型【无块I/O】上的块I/O模型,这一点非常清楚。 在块I/O模型中,最重要的是,在块准备等待数据时,无法控制此过程,因此在非块I/O模型中将此过程从原始块更改为非块状态。 在数据未准备好之前,立即请求返回EWOULDBLOCK错误代码。数据准备好后,开始复制数据,数据的所有复制完成并返回结果。 然而,这种方法需要通过调用recvfrom函数来确定用户进程是否准备好进行数据访问,这具有一个很大的缺点,即CPU消耗非常大,并且会极大地影响系统性能

进程应用进程向系统内核发出请求,调用系统函数recvfrom读取数据。

如果系统内核没有准备好数据报,recvfrom系统函数会立即返回EWOULDBLOCK错误代码。

应用进程通过轮询连续向系统内核发出recvfrom数据请求

当系统内核中的数据包准备就绪时,将进入数据复制阶段

系统内核将数据从内核空间复制到用户空间。 在这个阶段被屏蔽了

数据复制完成,应用进程启动的recvfrom函数恢复正常

形象

I/O复用模型【I/O multiplexing】基于无阻塞I/O模型,我们进一步进行优化,将整个原过程分为2个阶段,判断系统内核内的数据是否准备好的过程和任何一个或多个软盘数据准备好后,立即返回应用进程,应用进程通过调用系统中的recvfrom函数复制数据。 此过程的第一个阶段使用系统中的select/poll函数,第二个阶段使用原始recvfrom函数。 该过程可以在一个过程中判断并读取多个软盘的数据准备情况,大大节约了每个软盘的成本

进程应用进程通过系统内核发起请求,并调用select/poll系统函数来检测是否已准备好与一个或多个文件描述符(fd )相对应的数据。 如果其中一张软盘的数据未就绪,则select/poll函数将保持阻塞状态并等待数据

,当有一个或多个fd对应数据准备就绪后,select/poll函数返回可读状态的fd应用进程根据系统函数select/poll返回的处于可读状态的fd,有针对性的发起系统函数recvfrom调用请求数据系统内核接收到应用进程数据请求,开始进行数据拷贝,将数据从内核空间拷贝到应用空间数据拷贝完成,应用进程发起的recvfrom函数返回成功,应用进程开始下一步的数据处理 示意图

信号驱动I/O模型【signal blocking I/O】

I/O多路复用模型解决了一个线程同时监控多个fd的问题,但是select是采用轮询的方式来监控多个fd的,通过不断的轮询fd的可读状态来知道是否就可读的数据,因为大部分情况下的轮询都是无效的,所以在这样的基础上有进一步的做了改进,信号驱动I/O模型就产生啦。信号驱动I/O模型通过调用系统中的sigaction函数建立一个SIGIO的信号联系,当内核数据准备好之后再通过SIGIO信号通知用户进程准备好后的可读状态,当应用进程捕获到可读状态的信号后,再向系统内核调用recvfrom函数发起读取数据的请求,因为信号驱动I/O模型下应用线程在发出信号监控后即可返回,不会阻塞,同时也可以监控多个fd的可读状态。

处理流程 应用进程建立SIGIO的信号处理程序,调用系统函数sigaction,向系统内核进行注册,注册完成即返回注册结果当系统内核中对应的数据报准备就绪后,系统内核会发出应用进程注册的SIGIO信号量,应用进程捕获系统内核发出的SIGIO信号量应用进程通过调用系统函数recvfrom发起向系统内核的数据请求,系统内核接受到请求后开始将数据从内核空间向应用空间拷贝,该过程进程阻塞数据拷贝完成,应用进程发起的recvfrom函数返回成功,应用进程开始下一步的数据处理 示意图

异步I/O模型【asynchronous I/O】

前面的四种同步I/O模型中,不管是哪一种方式,数据在通过内核空间向应用空间拷贝的这个过程中,用户进程都是阻塞的,产生这个问题的根源是由于触发数据从内核空间向应用空间拷贝的这个行为是应用进程来发起,所以应用进程在整个过程中一定是阻塞的,在这样的基础上,在系统的不断发展过程中,系统层面逐渐具备了直接通过系统内核来触发数据从内核空间向应用空间拷贝的能力,这样,异步I/O模型就应运而生啦。异步I/O的整个思路是将数据拷贝的这整个事情交给系统来做,而不是应用进程,应用进程只是作为整个事情的发起人和最终结果的处理人,对整个过程完全不进行参与,保证了应用进程在整个处理过程的非阻塞。

处理流程 应用进程通过调用系统函数aio_read,向系统内核发起数据请求通知并注册指定信号量,该事件处理完成立即返回系统内核收到数据请求调用,开始数据的准备以及后续的数据拷贝,当数据准备就绪后,系统内核发出数据拷贝命令,将数据从内核空间向应用空间拷贝,数据拷贝完成,系统内核发出aio_read中指定的信号量,应用进程捕获到指定的信号量并进行下一步的数据处理流程 示意图

总结 阻塞与非阻塞和异步的关系

阻塞与非阻塞都是针对于同步I/O来说的,因为只有在同步I/O需要数据请求发主动去发起数据请求并等待数据准备就绪的这个过程中才会出现阻塞或者非阻塞的情况,而异步I/O发起请求只是通知系统进行数据的准备及处理,然后等待系统的回调,并没有实际参与到这个数据处理过程中,所以不存在阻塞或者非阻塞的情况。

处理效率比较

单纯从理论上来讲的话,不同I/O模型的处理效率是这样排序的:阻塞I/O < 非阻塞I/O < I/O多路复用 < 信号驱动I/O < 异步I/O ,但是在实际环境中,由于异步I/O整体的复杂性和它所带来的效率提高的比例,造成了我们在实际工作中用到的异步I/O并不多,netty在前期支持了异步I/O这种模型,也就是netty中的AIO,但是在后续的更新中逐渐的淘汰了,据说是由于在实际应用场景中发现对处理效率的提高非常有限。

信号驱动I/O模型和异步I/O模型的区别

同步的信号驱动I/O模型和异步I/O模型在整体的设计过程中有很多的相似之处,它们都是通过向系统内核注册信号量的方式来等待系统内核的处理通知的,但是这个里面有一个最大的区别是:数据的拷贝命令的发起人是不同的,信号驱动I/O模型是应用进程收到SIGIO信号后再调用函数recvfrom去触发系统内核中的数据拷贝过程,而且这个拷贝过程中应用进程是阻塞的,但是异步I/O的出发系统内核中的数据拷贝过程是有系统内核直接发起,这个过程对于应用进程来说是无感知的,直到数据拷贝完成才会通过信号量的方式来通知系统进程,这个拷贝的过程对于应用进程来说完全是无阻塞的

不同I/O模型流程比较

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。