对阻塞,非阻塞,同步,异步的理解一直很模糊,看了很多文章,也跟同学讨论了一下,写一下自己的理解,当然这个理解还是局限于自己当前的知识水平。有不对的地方,还请纠正
阻塞:
网上有说法是,阻塞就是这个线程不能干别的了,只能在这里等着。
我觉得这个说法不是很准确,我理解阻塞其实就是进程切换到阻塞态,不能占有CPU,这时候,进程就停止在这个阻塞调用上,不能继续向下执行。
Java的普通I/O就是BIO(Blocking I/O)。
Reads a byte of data from this input stream. This method blocks if no input is yet available.
上面是FileInputStream中的read()的描述,当调用read()时,这个程序的进程会被切换到阻塞态,直到操作系统准备好数据,进程才会切换到就绪态。所以说,This method blocks if no input is yet available.
在操作系统的五种I/O模型中,阻塞I/O如下
recvfrom是一个系统调用,这个系统调用并不会立即返回,会等到数据准备完成并且被拷贝到应用程序的缓冲区中,或者出现了一个错误,才会返回。
非阻塞:
有了阻塞的理解之后,就很简单,也就是说这个方法不会使进程被切换到阻塞态。
Java中的NIO(Non-Blocking I/O)就是一个非阻塞的I/O。
NIO中的Selector中可以注册多个channel,可以使用Selecotr中的select方法可以获得事件发生的channel。
This method performs a blocking selection operation. It returns only after at least one channel is selected, this selector’s wakeup method is invoked, or the current thread is interrupted, whichever comes first.
上面是select()的的方法描述,第一句话就是a blocking selection operation ,一个阻塞的选择操作。不是说非阻塞吗?实际上这个非阻塞是体现在I/O上。
我们看第二句话,It returns only after at least one channel is selected,所以这个channel什么时候会被选择,就是我们将channel注册在Selector上要监听的事件(Accept,Connect,Read,Write这四个事件)发生的时候。
所以可以认为,当我们调用read或者write的时候,这个数据已经准备好了,可以直接读写,在I/O时不会阻塞。
我们看一下操作系统中的I/O模型,非阻塞I/O如下
实际上,当调用recvfrom时,不会使进程进入阻塞态。如果数据没有准备好,他会立刻返回EWOULDBLOCK。就如同Selector中的selectNow()方法,下面是selectNow()方法的描述.
This method performs a non-blocking selection operation. If no channels have become selectable since the previous selection operation then this method immediately returns zero
操作系统中的I/O模型,多路复用I/O模型也是非阻塞的,如下
实际上Java的NIO原理就是与这个多路复用I/O相同,也许NIO就是用这个实现的。
同步
同步,我理解就是事情一步一步做,必须有个先后次序,上一步干不完,你不能干别的去。
Java NIO被称为是同步非阻塞的,非阻塞我们已经说了。什么是同步,在NIO中进程还是会阻塞在select中,因为没有事件发生,这个程序就不能往下执行。
如果学过组成原理的话,实际上I/O方式中程序查询方式就是同步的
在外设没有准备就绪之前,CPU需要一遍一遍的查询外设状态。
异步
异步就不一样了,在调用一个异步的方法后,会立即返回。然后就可以干别的事情了,这个方法执行完毕或者出错时,会通过状态,通知,回调来通知调用者。
在组成原理的中断方式中, CPU 在程序中安排好在某一时刻启动某一台外设,然后 CPU 继续执行 原来程序,不需要像查询方式那样一直等待外设准备就绪。一旦外设完成数据传送的准备工作,便主动向 CPU 发出中断请求,请求 CPU 为自己服务。
操作系统中的I/O模型,异步I/O模型如下
进程发起系统调用后无需等待,直接返回,进行后续的其它任务,由内核完成I/O操作之后通过回调通知到进程,或者执行回调函数。
说点题外话,最近读《现代操作系统》,提到单线程web服务器的设计,我理解异步的就是有限状态机的体现吧.
来源:CSDN
作者:德莫
链接:https://blog.csdn.net/weixin_45626962/article/details/104121755