IO模型:同步与异步,阻塞与非阻塞

Unix下的IO可以区分为5I/O模型

  • 阻塞式I/O
  • 非阻塞式I/O
  • I/O复用(selectpoll
  • 信号驱动式I/OSIGIO
  • 异步I/O

Unix下一个输入操作可分为两个步骤:

  1. 等待数据准备好
  2. 从内核向进程复制数据

对于一个网络I/O的输入操作也是一样:

  1. 等待数据从网络到达,复制到内核中的某个缓冲区
  2. 把数据从内核缓冲区复制到进程缓冲区


阻塞式I/O


Linux默认情况下,所有套接字都是阻塞的。一个从网络读数据的流程如下图:



我们在进程中,让套接字调用读操作(recvfrom函数),这个系统调用让程序在应用进程空间中运行切换到内核空间中运行,系统内核等待网络数据包分组到达,复制到内核中的缓冲区,准备好数据后将数据从内核复制到进程的缓冲区,这时向进程返回成功信号或过程中出错返回错误信号。在这段期间中对于整个进程是阻塞的,直到内核返回信号阻塞才停止,这就是阻塞式I/O模型。

阻塞式I/O特点就是在IO的两个步骤中一直是block的。



非阻塞式I/O


可以将套接字设置为非阻塞模式,同样是上面的例子,新的流程如下图:


从图看出,在非阻塞模式下,IO操作的两个步骤中,第一步进程并不阻塞,调用recvfrom函数后内核等待数据过程,返回给进程EWOULDBLOCK错误,进程反复(轮询)调用recvfrom函数,直到内核缓冲区中数据准备好了,这时将数据从内核缓冲区复制到进程缓冲区,成功后返回给进程成功信号。

这种模式与上面的相比,第一个步骤进程不阻塞,第二个步骤才阻塞。不过这种方式频繁在用户态和内核态中切换,会耗费大量CPU时间,所以这种IO模式并不常遇到。


I/O复用


I/O复用模型调用selectpoll函数(目前主流都使用epoll,是select/poll的增强版本),进程阻塞在两个步骤调用的某一个之上,而不是两个都阻塞。下面是IO的流程图:


如上图,进程阻塞于select函数,当内核数据准备好后,返回可读条件,进程在调用recvfrom把数据从内核缓冲区复制到进程缓冲区。

可以看出I/O复用模型,在IO操作的两个步骤中,进程分别都阻塞了,看似和阻塞式I/O相比,还多了一次系统调用。如果只有一次IO操作的话,select反而没有优势了,不过select的优势在于可以等待多个描述符就绪。内核监视select负责的所有socket,当有一个socket中的数据准备好了,select就返回,用户进程就能调用recvfrom将数据从内核缓冲区复制到用户进程缓冲区进行下一步操作了。

在多并发的场景下,select的阻塞和recvfrom的阻塞可以在不同的线程中分别进行,这样能大大提高IO的操作性能。这也是I/O复用在实际场景下被经常使用的原因。


信号驱动式I/O


我们知道要杀死进程( kill ),就是向进程发送信号来终止进程。这种 IO 模型也是一样,使用信号,让内核在描述符就绪时发送 SIGIO 信号通知进程。


进程调用sigaction安装一个信号处理函数,系统调用立即返回,进程不阻塞继续工作。当数据准备好后,内核为进程产生一个SIGOI信号,然后我们就可以再信号处理程序中调用recvfrom从内核缓冲区读取数据了。


异步I/O


异步I/O机制原理和信号驱动一样,调用异步IO的函数,告知内核启动某IO操作,内核完成整个IO操作(等待数据和复制到进程缓冲区)后信号通知进程,进程就可以直接从进程缓冲区读取数据。异步IO的流程图如下:


和信号驱动IO的区别在于信号驱动IO是内核通知进程可以从内核缓冲区复制数据,而异步IO是内核通知进程整个IO操作已完成,可以直接从进程缓冲区拿数据了。


同步I/O和异步I/O


从上面总结的5种模型可以看出,前4种模型区别都在于第一阶段,它们的第二阶段是一样的,进程阻塞于recvfrom调用。第5种模型进程都不阻塞,所以也可以将IO归类为两种:

同步IO:请求进程阻塞,直到IO操作完成。

异步IO:不导致请求进程阻塞。

如下图所示,只有异步IO模型才是真正的进程不阻塞,其他模型都有阻塞的阶段。



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值