深入浅出Unix IO模型
Posted 码农沉思录
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了深入浅出Unix IO模型相关的知识,希望对你有一定的参考价值。
前言
在介绍Unix IO模型之前,我们先来说说什么是IO。根据维基百科的定义,IO 指的是输入输出,通常指数据在内部存储器和外部存储器或其他周边设备之间的输入和输出。简而言之,从硬盘中读写数据或者从网络上收发数据,都属于IO行为。
以数据输入为例,一个输入操作,通常可以分为2个阶段:
等待操作系统内核把数据准备好
将数据从操作系统内核复制到用户进程空间
这里有一个问题就是,假如操作系统内核还没把数据准备好,这个时候用户进程要怎么处理?是一直等待直到数据准备好,还是隔一段时间来询问一次,又或者是操作系统把数据准备好后去通知用户进程呢?虽然一个IO操作只有2个阶段,但是根据IO是否阻塞、是否同步,却可以把IO再细分成不同的模型。实际上,在Unix网络编程中一共有5种不同的IO模型,下文将进行详细介绍。
Unix IO模型
阻塞式IO模型
阻塞式IO是所有IO模型中最简单的一种,在这种模型下,所有IO操作都是阻塞的。以套接字接口为例,在进程空间调用recvfrom,其系统调用直到数据包到达且被复制到应用进程的缓冲区或者发生错误时才返回,在此期间会一直等待,因此被称为阻塞式IO模型。
阻塞式IO就像是在排队买火车票一样,如果前面排队的人很多,你是没办法抽身走开的,只能干等着,如果走开一会儿就得重新排队了,因此阻塞式IO效率是十分低下的。
非阻塞式IO模型
非阻塞式IO模型跟阻塞式IO模型的主要区别是如果操作系统内核没有把数据准备好,recvfrom会直接返回一个错误,而不是一直阻塞。
非阻塞式IO就像是去小饭馆吃饭一样,你去的时候如果人很多,你可以先取号,取完号之后可以先在周围逛逛,等时间差不多了再到饭馆看看是否轮到自己就餐了。与阻塞式IO相比,非阻塞IO效率有所提升,因为不用一直待在原地“排队”,不过还是有一个缺点就是,要不断地去询问操作系统内核是否已经把数据准备好了。
IO复用模型
Unix中提供了select/poll来使用IO复用,这样一来用户进程就可以阻塞在select/poll上,而不是阻塞在具体的IO操作上。当操作系统内核将数据准备好之后,select/poll会返回可读条件,然后用户进程再调用recvfrom来将数据复制到用户进程空间。使用多路复用的好处是,我们可以等待多个文件描述符就绪,即select/poll会帮我们侦测多个文件描述符是否就绪,从而使得用户进程不必阻塞于具体的IO操作。
信号驱动式IO模型
信号驱动式IO是指让操作系统内核在文件描述符就绪时发送信号给用户进程,这样一来用户进程只要调用sigaction后就能立即返回,不会被阻塞。当操作系统的文件描述符就绪时,会发送信号给用户进程,用户进程再调用recvfrom开始IO操作。
异步IO模型
异步IO模型指的是告诉操作系统内核启动某个操作,并让操作系统内核在完成整个操作后通知用户进程。其与信号驱动式IO的区别是信号驱动式IO模型是操作系统内核通知我们何时开始一个IO操作,而异步IO模型是操作系统内核通知我们该IO操作何时完成。
异步IO模型就像是委托别人去银行办理业务一样,只要将要办的业务以及相关的证件交给委托人,委托人就会帮你去办理,期间你是不需要跑腿的,还是可以做自己的事情,当委托人办完业务后再通知你办理的结果就行了。所以异步IO模型是效率最高的IO模型了,因为你自己不需要“跑腿”,只要敬候佳音就行了。
关于Unix IO模型的介绍就到这里了,如果觉得这篇文章对你有帮助,可以扫描下方二维码进行关注。
以上是关于深入浅出Unix IO模型的主要内容,如果未能解决你的问题,请参考以下文章
《深入理解计算机系统》Tiny服务器4——epoll类型IO复用版Tiny
Linux_Unix系统编程chapter5 深入探究文件IO