JAVA-000

返回Week_02主页

IO 模型学习心得

根据秦老师的讲解,同时参考如下文档:

汇总如下几个基本知识点,方便日后理解:

阻塞(blocking) vs 非阻塞(non-blocking)

一个完整的IO读请求操作包括两个阶段:

  1. 等待数据就绪;
  2. 数据拷贝(将数据从内核拷贝到用户空间)。 阻塞和非阻塞的区别就在于第一个阶段,如果数据没有就绪,在查看数据是否就绪的过程中是一直等待,还是直接返回一个标志信息。
    以读操作为例:当用户线程发起一个IO读请求时,内核会去查看要读取的数据是否就绪,对于阻塞IO来说,如果数据没有就绪,则会一直在那等待,直到数据就绪;对于非阻塞IO来说,如果数据没有就绪,则会返回一个标志信息告知用户线程当前要读的数据没有就绪,当数据就绪之后,再将数据拷贝到用户线程。

同步(synchronous) vs 异步(asynchronous)

在说明synchronous IO(同步IO)和asynchronous IO(异步IO)的区别之前,需要先给出两者的定义。Stevens给出的定义(其实是POSIX的定义)如下:

两者的区别就在于synchronous IO做IO operation的时候会将process阻塞。按照这个定义,blocking IO,non-blocking IO,IO multiplexing都属于synchronous IO。有人可能会说,non-blocking IO并没有被block啊。这里有个非常狡猾的地方,定义中所指的IO operation是指真实的IO操作,就是例子中的recvfrom这个system call。non-blocking IO在执行recvfrom这个system call的时候,如果kernel的数据没有准备好,这时候不会block进程。但是,当kernel中数据准备好的时候,recvfrom会将数据从kernel拷贝到用户内存中,这个时候进程是被block了,在这段时间内,进程是被block的。而asynchronous IO则不一样,当进程发起IO 操作之后,就直接返回再也不理睬了,直到kernel发送一个信号,告诉进程说IO完成。在这整个过程中,进程完全没有被block。 注意:select,poll,epoll都属于IO多路复用,而IO多路复用又属于同步的范畴,故,epoll只是一个伪异步而已。

非阻塞(non-blocking) vs 异步(asynchronous)

non-blocking IO和asynchronous IO的区别还是很明显的:

五种IO模型比较

五种IO模型的类型如下: IO Model Summary
五种IO模型的比较如下: IO Model Comparison
用买票作类比,总结一下: