IO中的同步/异步,阻塞/非阻塞

同步与异步

在java IO中同步异步是针对用户态和内核态的概念,用户程序要想发送数据要经过下面几个步骤:
1.应用程序将要发送的内容写入用户内存空间。
2.应用程序向操作系统内核发送系统调用
3.操作系统将用户空间的数据读入内核缓冲区。
4.操作系统通知网卡来读取内核缓冲区的数据,此时CPU可以处理其他事情。
5.网卡从指定的内核空间读取数据。
6.网卡将数据转换成二进制数据,以比特流的形式输出。

同步和异步是针对应用程序和内核的交互而言
同步是用户进程触发IO操作并等待或者轮询的去查看IO操作是否就绪.
异步是指用户进程触发IO操作以后便开始做自己的事情,当IO操作已经完成的时候会得到IO完成的通知。

同步和异步的主要区别就是在用户程序通过系统调用IO操作时是否需要等待和轮询,以便查看操作系统是否完成了IO的就绪。

这里的等待IO指的是数据从应用程序拷贝到内核空间(或从内核空间拷贝到应用程序)的过程。

阻塞和非阻塞

阻塞和非阻塞是针对于应用程序在访问数据的时候,根据IO操作的就绪状态来采取的不同方式,阻塞方式下读取或者写入过程一直等待结果,而非阻塞方式下,读取或者写入过程会立即有一个返回值。

阻塞情况下需要等待执行结果,非阻塞情况下立即返回结果(不管操作成功还是失败)。结合同步和异步的理解过程。
阻塞:当用户线程发起一个IO请求的时候,请求会到达内核,内核获得数据后,将数据从内核空间拷贝到用户空间,期间,当内核未将数据准备好时,用户线程一直处于阻塞状态(用户线程不会获得反馈结果)。
非阻塞:当用户程序发起IO请求时,不用等到内核准备好数据才能返回,而是可以立即返回。(不论什么状态都获得反馈结果)没有被阻塞住。

java中的IO

同步阻塞IO:用户进程发起一个IO请求后,必须等待IO操作完成,只有当真正完成了IO操作后,用户进程才能运行。java传统的IO模型属于此种方式。
同步非阻塞IO:在此种方式下,用户进程发起一个IO操作以后可立即返回做其他事情,但是用户进程需要时不时的询问IO操作是否就绪。这就要求用户进程不断的去询问。从而引入不必要的CPU资源浪费,目前java的NIO就属于同步非阻塞IO。
异步阻塞IO:当用户进程发起一个IO操作后,不等待内核IO操作完成,等待内核操作完成后会通知应用程序,这其实就是同步和异步的区别。同步是必须等待或者主动询问IO是否操作完成;其中为什么是阻塞呢,因为此时是通过select系统调用来完成的,而select函数本生的实现方式是阻塞的,而采用select函数有个好处就是可以同时监听多个文件
句柄,从而提高系统的并发性!
异步非阻塞IO:用户进程只需要发起一个IO操作然后立即返回,等IO操作真正的完成以后,应用程序会得到IO操作完成的通知。此时应用进程只需要对数据进行处理就好了,不需要进行实际的IO操作,真正的IO读取和写入操作已经由内核完成了。

你可能感兴趣的:(IO中的同步/异步,阻塞/非阻塞)