Linux 五种IO模型

IO模型的意义:应对进程在运行过程中申请资源时产生的性能开销

IO具体开销来源:对于一次IO访问,数据会先被操作系统内核的缓冲区,然后才会被拷贝到应用程序的地址空间,所以一个 read 操作会分为两个阶段:

  • 等待数据准备
  • 讲数据从内核拷贝到进程中
    常见的IO模型:阻塞、非阻塞、IO多路复用、异步,接下来一一介绍

同步阻塞IO

用户程序每次执行系统调用,进程就会进入阻塞,read的两个阶段过程中整个进程都是在阻塞中的,不能去处理别的IO,进程直接把CPU交出去了,只有数据准备完毕了,应用程序才会继续。
对于用户来说,这种模式显然性能太低。

同步非阻塞IO

用户程序进行系统调用时,如果数据没有准备好,会返回一个 error,并且进程并没有被阻塞,内核会马上返回给进程,然后程序可以去做些别的事,隔一段时间再来系统调用,“查看”资源准备情况,直到资源准备完毕,这也叫“轮询”。当发现资源准备好了,再进入拷贝数据到进程,而这个过程是阻塞的。
因每过一段时间才去 read ,但数据准备完毕可能是在两次 read 中间,所以导致资源的吞吐量下降了,任务完成的相应延迟增大了。而且轮询也会消耗大量的CPU时间。

IO多路复用

未解决上述非阻塞IO的问题,IO多路复用将监视数据是否准备完毕的任务交给了内核,并且可以实现同时对多个IO端口进行监听,其中任何一个准备完毕了,都会返回可读,然后再系统调用,讲数据从内核拷贝到进程,当然这个过程还是阻塞的。
目前IO多路复用的三种方式是 select,poll,epoll,它们的区别会在之后的文章中解释。
实际上当要处理的连接数不多的时候,IO多路复用效率甚至不如阻塞式IO,因为 select 本身也是系统级调用,也就是比阻塞IO多了一个。
当有过个客户端的请求到达服务器时,可以利用多线程或者IO多路复用处理。相比多线程,IO多路复用因为可以做到单线程就可以处理多个请求,而省去了线程创建销毁的开销,也降低了维护成本。

以上三种IO模型,虽然在等待数据准备时采用的策略不同,但无一例外,都是进程主动等待或者轮询来了解内核的情况,所以都是同步模式。
高并发场景下一般用同步非阻塞而并非用多线程阻塞,因为在大部分情况下并发度要远大于并行度,在高并发的情况下创建大量线程开销是非常大的。

信号驱动IO

进程进行信号驱动IO后不阻塞,等数据准备好了会收到SIGIO信号,然后进行信号处理。

异步非阻塞IO

用户进程进行aio_read系统调用后,内核会马上返回一个结果,然后程序就去干别的事情了,从准备数据,到数据拷贝都是内核干的,都做完后,再向进程发送信号,进程接到后再处理,所以整个IO过程,都是非阻塞的。
所以相比同步IO,进程直接将整个IO操作交给了别人,自己也完全不用去主动检查情况,相反是内核来通知它,而对于同步IO,即使是非阻塞IO,也要每隔一段时间去检查内核,并且数据的拷贝也要自己完成,这就是同步异步的区别。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值