I/O模型


 

进程向内核进行系统调用申请IO,内核将资源从IO调度到内核的buffer中(wait阶段),内核还需将数据从内核buffer中复制(copy阶段)到web服务器进程所在的用户空间,才算完成一次IO调度。这几个阶段都是需要时间的。根据wait和copy阶段的处理等待的机制不同,可将I/O动作分为如下五种模式:


Unix下共有五种I/O模型 
(1)阻塞I/O 
(2)非阻塞I/O 
(3)多路复用I/O(select和poll) 
(4)信号驱动I/O(SIGIO) 
(5)异步I/O

Linux上的前四种I/O模型的“执行”阶段都是同步的,只有最后一种才做到了真正的全异步。

阻塞和非阻塞:

阻塞和非阻塞指的是执行一个操作是等操作结束再返回,还是马上返回。

比如餐馆的服务员为用户点菜,当有用户点完菜后,服务员将菜单给后台厨师,此时有两种方式:

§  第一种:就在出菜窗口等待,直到厨师炒完菜后将菜送到窗口,然后服务员再将菜送到用户手中;

§  第二种:等一会再到窗口来问厨师,某个菜好了没?如果没有先处理其他事情,等会再去问一次;

第一种就是阻塞方式,第二种则是非阻塞的。

同步和异步:

同步和异步又是另外一个概念,它是事件本身的一个属性。还拿前面点菜为例,服务员直接跟厨师打交道,菜出来没出来,服务员直接指导,但只有当厨师将菜送到服务员手上,这个过程才算正常完成,这就是同步的事件。同样是点菜,有些餐馆有专门的传菜人员,当厨师炒好菜后,传菜员将菜送到传菜窗口,并通知服务员,这就变成异步的了。其实异步还可以分为两种:带通知的和不带通知的。前面说的那种属于带通知的。有些传菜员干活可能主动性不是很够,不会主动通知你,你就需要时不时的去关注一下状态。这种就是不带通知的异步。

对于同步的事件,你只能以阻塞的方式去做。而对于异步的事件,阻塞和非阻塞都是可以的。非阻塞又有两种方式:主动查询和被动接收消息。被动不意味着一定不好,在这里它恰恰是效率更高的,因为在主动查询里绝大部分的查询是在做无用功。对于带通知的异步事件,两者皆可。而对于不带通知的,则只能用主动查询。

全异步I/O

回到I/O,不管是I还是O,对外设(磁盘)的访问都可以分成请求和执行两个阶段。请求就是看外设的状态信息(比如是否准备好了),执行才是真正的I/O操作。在Linux 2.6之前,只有“请求”是异步事件,2.6之后才引入AIO(asynchronousI/O )把“执行”异步化。别看Linux/Unix是用来做服务器的,这点上比Windows落后了好多,IOCP(Windows上的AIO,效率极高)在Win2000上就有了。所以学linux的别老觉得Windows这里不好那里不好(Windows的多线程机制也由于linux)。



1、阻塞I/O模型 

应用程序调用IO函数,导致应用程序阻塞,等待数据准备好。如果数据没有准备好,则程序则阻塞等待。若果数据准备好了,从内核空间拷贝到用户空间。 

这里写图片描述


2、非阻塞I/O模型 
我们把一个套接字设置为非阻塞就是告诉内核,当所请求的I/O操作无法完成时,不要将进程睡眠,而是返回一个错误。这样I/O操作函数将不断的测试数据是否准备好,如果没有准备好,继续测试,直到数据准备好为止。在这个不断的测试中,会大量的占用CPU的时间。 
这里写图片描述 



3、多路复用I/O 
I/O复用模型会用到select或者poll函数,这两个函数也会使进程阻塞,但是和阻塞I/O所不同的是,这两个函数可以同时阻塞多个I/O操作。而且可以同时对多个写操作的I/O函数进行检测,直到有数据可读或可写时,才真正调用I/O操作函数。 
这里写图片描述 



4、信号驱动I/O模型 
首先我们允许套接字接口进行信号驱动I/O,并安装一个信号处理函数,进程继续运行并不阻塞。当数据准备好时,进程会收到一个SIGIO信号,可以在信号处理函数中调用I/O操作函数处理数据。 
这里写图片描述 


5、异步I/O模型 
调用aio_read函数,告诉内核描述字,缓冲区指针,缓冲区大小,文件偏移以及通知方式,然后立即返回。当内核将数据拷贝到缓冲区后,再通知应用程序。 
这里写图片描述 
几种I/O模型的比较 
前四个模型都是同步I/O模型,最后一个是异步I/O。五种I/O模型读取数据都分两个阶段完成。 
这里写图片描述 
前四种模型的第一个阶段基本相同,第二个阶段基本系统,都是将数据从内核中拷贝到调用者的缓冲区。而异步I/O的两个阶段都不同于前四个模型。 
网络编程的四种调用方式 
阻塞与非阻塞 
(1)、阻塞 
阻塞调用是指调用结果返回之前,当前线程会被挂起(线程进入非可执行状态,在这个状态下,CPU不会分配时间片,即线程暂停运行)。函数只有在得到结果之后才会返回。 
阻塞: 如果条件未就绪,’你’必须死等它就绪;进程睡眠(睡眠的缺点就是会让出CPU控制权) 
有的人会将阻塞和同步调用弄混,实际上二者是不同的。对于同步调用而说,很多时候线程是激活的,只是从逻辑上当前函数没有返回而已。 
(2)、非阻塞 
非阻塞和阻塞的概念相对应,指在不能立刻 得到结果之前,该函数不会阻塞当前线程,而会立刻返回。 
非阻塞:如果条件未就绪,’你’可以转身作别的事情;进程可以作任何想做的事情,不过通常是低效的轮询。(轮询的特点是CPU寄存器一直被当前进程使用。轮询不是一种好的方式,可以使用wait/notify机制)

同步于异步 
(1)、同步 
进程同步就是指在发出一个函数调用时,在没有得到结果之前,该调用就不返回。 
(2)、异步 
异步的概念和同步相对。当一个异步过程调用发出后,调用者不能立刻得到结果。实际处理这个调用的部件在完成后,通过状态、通知和回调来通知调用者。 
同步是阻塞模式,异步是非阻塞模式。

容易混淆的知识点 
同步和异步关注的是消息通信机制 (synchronous communication/ asynchronous communication) 
阻塞和非阻塞关注的是程序在等待调用结果(消息,返回值)时的状态.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值