当前位置: 首页 > 科技观察

Linux-I-O模型详解

时间:2023-03-17 10:46:18 科技观察

I/O简介I/O通常包括内存IO、网络I/O、磁盘I/O等,但我们通常说的网络I/O和磁盘I/欧。网络I/O:本质是socket读取每一个I/O请求,会分为两个阶段:第一步:等待数据,即数据从磁盘到内核内存;先从磁盘文件加载数据到内核内存空间(buffer),等待数据准备完成,耗时较长。第二步:拷贝数据,即数据内核内存到进程内存;将数据从内核缓冲区拷贝到用户空间的进程内存中,时间比较短。Web请求处理流程1.客户端向服务器网卡发起情况2.服务器网卡收到请求后,转交给内核处理3.内核将请求发送给工作在user中的Web服务器进程根据请求对应的socket空间4.根据用户的请求,web服务器进程向内核进行系统调用,申请相应的资源(如:客户端获取图片)5.内核发现web服务器进程请求一个存储在本地硬盘上的资源,于是通过驱动程序连接到磁盘6.内核调用磁盘获取需要的资源7.内核将资源存储在自己的缓冲区中,并通知Web服务器process8.Webserver进程通过系统调用获取资源,复制到进程自己的buffer中9.webserver进程形成response,通过s再次发送给kernel系统调用以响应请求。10.内核向网卡发送响应。11、网卡向用户发送响应。通过这么复杂的过程,一个请求就完成了。简单来说就是:用户请求——》投递到用户空间——>系统调用——》内核空间——>内核到磁盘读取图片资源——》返回用户空间——>响应用户上面的简单解释,客户端请求web服务器,在这个过程中,有两个I/O过程:一个是客户端请求的网络I/O,一个是web服务器请求的镜像磁盘I/O。I/OModelNouns说到I/O模型,就会涉及到同步、异步、阻塞、非阻塞这些词,下面分别解释这些词的概念Blockingandnon-blockingBlockingandnon-blocking指的是执行操作时,操作完成后返回结果,或者立即返回结果。阻塞:指IO操作需要完全完成才返回用户空间。在调用结果返回之前,调用者被挂起(当前线程进入不可执行状态,在该状态下,CPU不会分配时间片,线程将被挂起运行)只有在返回结果时才进入激活状态到达了;阻塞示例:海底捞服务员给你点单,点完后,服务员发消息给后厨,你就在桌边等,等厨师放好汤锅,等菜和小菜都做好了,就可以开始吃饭了并送到您的餐桌。上菜过程中不能离开,因为你离开后,服务员上菜了却找不到你,所以你可以等。这个时候你处于阻塞等待状态,也就是我之前说的,你是调用者,你被挂起进入不可执行状态。非阻塞(nonblocking):是指在I/O操作调用后立即返回一个状态值给用户,而不用等到I/O操作完全完成,直到最后调用者才会被挂起返回调用结果;非阻塞示例:海底捞服务器为你下单。点好后,服务员会把消息传到后厨。三分钟后,你去后厨问,我的锅底或者肥牛卷做好了吗?后厨说不好,然后你去处理其他的事情,又过了五分钟,你跑到后厨问我有一个菜做好了吗,没有,你继续做其他的things,然后waited再问,这个时候是和I/O操作同时进行的,你没有挂起,你可以操作其他的东西,但是如果I/O操作完成了,需要马上accept。同步和异步同步/异步关注的是同步消息通信机制(synchronous):调用者等待被调用者返回消息后才继续执行。同步阻塞示例:去饭店吃饭,点了一份盖饭,然后在桌边等盖饭做好,自己端上桌。这是典型的同步阻塞。厨师为您做饭时,您需要一直在场。同步非阻塞示例:去饭店吃饭,点了一个盖饭。你点完饭,过了几分钟,觉得时间差不多了,就问老板饭好了没有。如果准备好了,就去上菜吧。最好晚点问,实时同步烹饪进度,轮流问,直到饭做好。这是同步非阻塞。异步:被调用者主动通过状态、通知或回调机制将被调用者的运行状态通知给调用者。I/O模型类型IO模型分为以下五类1.阻塞型:所有进程完全阻塞2.非阻塞型:如果没有数据缓冲区,立即返回EWOULDBLOCK3.I/O多路复用型(select和poll):在wait和copy阶段分别阻塞4.信号驱动I/O(SIGIO):在wait阶段不阻塞,在copy阶段阻塞(signal-drivenI/O),即,notification5.异步I/O(AIO):完全不阻塞的Blocking模式,当I/O完成后,提供信号阻塞I/O。说明:应用程序调用IOrecvfrom函数,这将导致应用程序阻塞。进入阻塞状态后,直到I/O操作完成才会返回;如果系统内核数据还没有准备好,那就等待数据准备好,因为调用了recvfrom函数,应用被阻塞了,所以一直在等待,什么也做不了。内核数据准备好后,将数据从内核拷贝到用户空间。复制结束后,I/O函数返回成功指示。注意:阻塞时,在I/O操作阶段为非阻塞I/O说明:当用户线程发起IO请求时,立即返回。但如果没有读取到数据,则返回字段为“EWOULDBLOCK”,用户线程需要不断发起IO请求,直到数据到来,才真正读取数据并继续执行。即“轮询”机制。在整个IO请求过程中,虽然每次发起IO请求后用户线程都可以立即返回,以便等待数据。仍然需要不断轮询,重复请求,消耗大量CPU资源;这是对CPU的浪费。一般这种模型很少用到,但是非阻塞IO特性在其他模型中用到了。I/O多路复用(select和poll)说明:I/O多路复用模型将使用select或poll功能。在I/O多路复用模型中,不是阻塞到I/O操作过程中,而是阻塞到select或poll函数中;以select为例:进程阻塞在select处,等待几个描述符中的一个变为可操作,如果不等待,会继续阻塞在第一阶段,如果等待一个描述符变为可操作的话可操作,调用recvfrom函数将数据复制到申请缓冲区。信号驱动I/O(SIGIO)说明:首先,我们让socket进行信号驱动I/O,并安装一个信号处理函数SIGIO。如果数据没有准备好,会立即返回结果,进程会继续工作,不会阻塞。当数据准备好后,系统内核会主动发送一个SIGIO信号给应用程序。应用程序接收到信号后,可以调用信号处理函数中的I/O操作函数recvfrom对数据进行处理。信号驱动I/O模型的优点是当数据报到达时,不会阻塞,主循环可以继续执行,只是等待处理程序的通知,或者数据准备好处理,或者数据报已准备好被读取。异步I/O(AIO)描述:当发出异步过程调用时,调用者无法立即得到结果。真正处理这个调用的组件完成后,通过状态通知和回调通知将输入输出操作通知给调用者。用户可以直接对I/O进行读写操作。这些操作告诉内核用户读写缓冲区的位置,以及内核在I/O操作完成后通知应用程序的方式,也就是上面说的通过状态通知或回调通知的通知方式。呼叫者。异步I/O的读写操作总是立即返回,但是没有返回结果说是否阻塞,因为异步I/O操作真正的读写操作已经被内核接管了,而内核在数据处理完成后产生一个信号,然后通知用户刚刚交给自己的事件已经处理完毕。五种I/O模型的总结和比较。五种I/O模型中,前三种属于同步I/O,后两种属于异步I/O。同步I/OBlockingI/ONon-blockingI/OI/Omultiplexing(selectandpoll)异步I/O信号驱动I/O(SIGIO)半异步异步I/O(AIO)全异步异步I/O和信号驱动I/O的区别在信号驱动I/O模式中,内核通知我们应用程序在可以复制时发送一个SIGIO信号。在异步I/O模式下,内核不会通知我们的应用程序,直到内核操作完成所有操作。