关于IO四种模型的理解

写在前面

本文是个人总结,相关知识讲解请看下面的两篇博文强推!!!!!!
https://blog.csdn.net/historyasamirror/article/details/5778378 五种io模型的解释
https://www.jianshu.com/p/6a6845464770 这个例子很好 详解io多路复用


首先要了解IO的过程。IO的第一个阶段:准备数据。对于network io来说,很多时候数据在一开始还没有到达(比如,还没有收到一个完整的UDP包),这个时候kernel就要等待足够的数据到来。当kernel一直等到数据准备好了,此时进入第二个阶段将数据从kernel中拷贝到用户内存,然后kernel返回结果(拷贝完),用户进程才解除block的状态,重新运行起来。

阻塞IO (blocking IO)

阻塞式IO会在这两个阶段发生阻塞,1.操作系统内核准备数据时,2.内核将数据拷贝至用户内存时。

非阻塞IO(nonblocking IO)

当内核数据没有准备好,请求read时,内核立马发送一个error给用户,用户此时知道数据没有准备好,便会先去做其他事,过一会继续来询问。一旦kernel中的数据准备好了,并且又再次收到了用户进程的readcall,那么它马上就将数据拷贝到了用户内存,然后返回。
一般采用轮询方式来发送read请求

IO多路复用 (IO multiplexing)

select/poll

一个select负责多个scoket,与阻塞io类似,不过阻塞io一次进程只负责一个scoket,而select/poll一个进程可以负责多个scoket,处理更多的连接。
当用户进程调用了select,那么整个进程会被block,而同时,kernel会“监视”所有select负责的socket,当任何一个socket中的数据准备好了,select就会返回。这个时候用户进程再调用read操作,将数据从kernel拷贝到用户进程。
用户进程还是被select阻塞的,因为只有找到一个返回结果的scoket,才能真正的读。
多路复用是同步非阻塞的,非阻塞体现在,当一个socket的数据没有准备好时,会立即返回结果继续询问其他socket,并不被数据没有准备好阻塞住。同步体现在,该进程只能执行select函数,并不能去做其他事,所以还是被select阻塞住了。

epoll

异步IO (asynchronous IO)

用户进程发起read操作之后,立刻就可以开始去做其它的事。而另一方面,从kernel的角度,当它受到一个asynchronous read之后,首先它会立刻返回,所以不会对用户进程产生任何block。然后,kernel会等待数据准备完成,然后将数据拷贝到用户内存,当这一切都完成之后,kernel会给用户进程发送一个signal,告诉它read操作完成了。

题外

阻塞和非阻塞是指进程访问的数据如果尚未就绪,进程是否需要等待,也就是未就绪时是直接返回还是等待就绪。 而同步和异步是指访问数据的机制,同步一般指主动请求并等待I/O操作完毕的方式,当数据就绪后在读写的时候必须阻塞,异步则指主动请求数据后便可以继续处理其它任务,随后等待I/O,操作完毕的通知,这可以使进程在数据读写时也不阻塞。

你可能感兴趣的:(linux)