5种I/O模型的分析

总结

  1. 同步阻塞(BlockingIO):最简单的一种IO模型,用户线程在进行IO操作的时候通常是个系统调用,用户线程会由用户空间进入内核空间,内核空间数据包准备好后会将数据拷贝到用户空间,这个时候线程在用户态继续执行。
  2. 同步非阻塞(Non-blocking IO):同步非阻塞IO即在同步阻塞的基础之上将socket设置为NONBLOCK。这样用户线程在发起IO操作之后可以立即返回,但是用户线程需要不断轮询来请求数据。
  3. IO多路复用(IO Multiplexing):即Reactor设计模式,多路复用模型从流程上和同步阻塞的区别不大,主要区别在于操作系统为用户提供了同时轮询多个IO句柄来查看是否有IO事件的接口(如select),这从根本上允许用户可以使用单个线程来管理多个IO句柄的问题。
  4. 异步IO(Asynchronous IO):即Proactor设计模式。在异步IO模型中,用户不需要去轮询IO事件,然后才进行数据的读取,处理;在异步IO模型中,IO事件就绪的时候,内核会开启一个独立的内核线程去执行执行IO操作,实现真正的异步IO。这个时候用户线程可以直接读取内核线程准备好的数据。
    多路复用IO模型和异步IO模型的区别主要是用户线程得知IO事件的时候在多路复用IO模型中,用户线程需要自己去处理IO,而在异步IO模型中数据已经由内核线程为用户线程准备好了。在实际应用中,在高效的IO应用中,最常见的是第三种IO模型,异步IO目前操作系统方面的支持并不是很好而且在性能数据上并不是很好看。

1 阻塞式IO模型

这里写图片描述
网络模型:
  在这个模型中,应用程序为了执行这个read操作,会调用相应的一个system call,将系统控制权交给内核,然后就进行等待(这个等待的过程就是被阻塞了),内核开始执行这个system call,执行完毕后会向应用程序返回响应,应用程序得到响应后,就不再阻塞,并进行后面的工作。

场景描述:
  在饭店领完号后,前面还有n桌,不知道什么时候到我们,但是又不能离开,因为过号之后必须重新取号。只好在饭店里等,一直等到叫号到我们才吃完晚饭,然后去逛街。中间等待的时间什么事情都不能做。

  • 优点: 能够及时返回数据,无延迟。
  • 缺点:对用户来说处于等待就要付出性能代价。

2 非阻塞IO模型

这里写图片描述
网络模型:
  当用户进程发出read操作时,调用相应的system call,这个system call会立即从内核中返回。但是在返回的这个时间点,内核中的数据可能还没有准备好,也就是说内核只是很快就返回了system call,只有这样才不会阻塞用户进程,对于应用程序,虽然这个IO操作很快就返回了,但是它并不知道这个IO操作是否真的成功了,为了知道IO操作是否成功,应用程序需要主动的循环去问内核。

场景描述:   
等待过程是在太无聊,于是我们就去逛商场,每隔一段时间就回来询问服务员,叫号是否到我们了,整个过程来来回回好多次。这就是非阻塞,但是需要不断的询问。

  • 优点:能够在等待的时间里去做其他的事情。
  • 缺点:任务完成的响应延迟增大了,因为每过一段时间去轮询一次read操作,而任务可能在两次轮询之间的任意时间完成,这对导致整体数据吞吐量的降低。

3 I/O复用模型

这里写图片描述
网络模型:
  和第二种一样,调用system call之后,并不等待内核的返回结果而是立即返回。虽然返回结果的调用函数是一个异步的方式,但应用程序会被像select、poll和epoll等具有多个文件描述符的函数阻塞住,一直等到这个system call有结果返回了,再通知应用程序。这种情况,从IO操作的实际效果来看,异步阻塞IO和第一种同步阻塞IO是一样的,应用程序都是一直等到IO操作成功之后(数据已经被写入或者读取),才开始进行下面的工作。不同点在于异步阻塞IO用一个select函数可以为多个文件描述符提供通知,提供了并发性。举个例子:例如有一万个并发的read请求,但是网络上仍然没有数据,此时这一万个read会同时各自阻塞,现在用select、poll、epoll这样的函数来专门负责阻塞同时监听这一万个请求的状态,一旦有数据到达了就负责通知,这样就将一万个等待和阻塞转化为一个专门的函数来负责与管理。

场景描述:

与第二个经常类似,饭店安装了电子屏幕,显示叫号的状态,所以在逛街的时候,就不用去询问服务员,而是看下大屏幕就可以了。(不仅仅是我们不用询问服务员,其他所有的人都可以不用询问服务员)

4 信号驱动IO模型

这里写图片描述
应用程序提交read请求,调用system call,然后内核开始处理相应的IO操作,而同时,应用程序并不等内核返回响应,就会开始执行其他的处理操作(应用程序没有被IO阻塞),当内核执行完毕,返回read响应,就会产生一个信号或执行一个基于线程的回调函数来完成这次IO处理过程。在这里IO的读写操作是在IO事件发生之后由应用程序来完成。异步IO读写操作总是立即返回,而不论IO是否阻塞,因为真正的读写操作已经有内核掌管。也就是说同步IO模型要求用户代码自行执行IO操作(将数据从内核缓冲区移动用户缓冲区或者相反),而异步操作机制则是由内核来执行IO操作(将数据从内核缓冲区移动用户缓冲区或者相反)。可以这样认为,同步IO向应用程序通知的是IO就绪事件,而异步IO向应用程序通知的是IO完成事件。

5 异步IO模型

这里写图片描述
异步IO与上面的异步概念是一样的, 当一个异步过程调用发出后,调用者不能立刻得到结果,实际处理这个调用的函数在完成后,通过状态、通知和回调来通知调用者的输入输出操作。异步IO的工作机制是:告知内核启动某个操作,并让内核在整个操作完成后通知我们,这种模型与信号驱动的IO区别在于,信号驱动IO是由内核通知我们何时可以启动一个IO操作,这个IO操作由用户自定义的信号函数来实现,而异步IO模型是由内核告知我们IO操作何时完成。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值