一、同步&异步
同步和异步指的是:当前线程是否需要等待调用方法执行完毕。
1.1 同步
同步是指一个进程在调用某个方法时会等待该方法返回结果,即调用方法不返回结果则会一直等待下去。
1.2 异步
异步是指一个进程在调用某个方法时不用等待该方法的返回结果,会马上进行下一步处理,至于调用结果则通过其他方式得到,例如:回调或者事件通知的方式。
1.3 总结
根据定义可以看出,同步逻辑比较直观;而异步是用于一些特定的场景,利用得当可以使程序更高效。
二、阻塞和非阻塞
阻塞和非阻塞通常是指访问特定资源时,若资源没有准备就绪时,线程是否会阻塞挂起等待;
什么是阻塞挂起
当前线程还处于 CPU 的时间片中,若此时访问没有准备就绪的数据时(会阻塞)此时调用阻塞的方法让出 CPU 时间片。
所以阻塞和同步都是需要等待,不同的是阻塞会挂起当前线程让出 CPU,而同步会一直占用 CPU 时间片。而非阻塞就是当访问资源没有准备就绪时,当前线程不会被阻塞而是通过其他方式间接的获取访问资源。
三、I/O 操作
提示
I/O 操作有两个步骤:
1、发起 I/O 请求;
2、实际 I/O 读写,即数据从内核缓存拷贝到用户空间;
3.1 阻塞 I/O 和非阻塞 I/O
阻塞 I/O
指用户线程发起 I/O 请求的时候,如果数据还未准备就绪(例如暂无网络数据接收),就会阻塞当前线程,让出 CPU。
非阻塞 I/O
指用户线程发起 I/O 请求的时候,如果数据还未准备就绪(例如暂无网络数据接收),也不会阻塞当前线程,可以继续执行后续的任务。
3.2 同步 I/O 和异步 I/O
同步 I/O
指用户线程发起 I/O 请求的时候,数据是有的,那么将进行步骤2(实际 I/O 读写,即数据从内核缓存拷贝到用户空间),这个过程用户线程是要等待着拷贝完成。
异步 I/O
指用户线程发起 I/O 请求的时候,数据是有的,那么将进行步骤2(实际 I/O 读写,即数据从内核缓存拷贝到用户空间),拷贝的过程中不需要用户线程等待,用户线程可以去执行其它逻辑,等内核将数据从内核空间拷贝到用户空间后,用户线程会得到一个“通知”。
在 I/O 场景下同步和异步说的其实是内核的实现,因为拷贝的执行者是内核,一种是同步将数据拷贝到用户空间,用户线程是需要等着的。一个是通过异步的方式,用户线程不用等,在拷贝完之后,内核会调用指定的回调函数。
四、总结
阻塞和非阻塞指的是发起 I/O 请求后,用户线程状态的不同,阻塞I/O在数据未准备就绪的时候会阻塞当前用户线程,而非阻塞 I/O 会立马返回一个错误,不会阻塞当前用户线程。
同步和异步是指,内核的 I/O 拷贝实现,当数据准备就绪后,需要将内核空间的数据拷贝至用户空间,如果是同步 I/O 那么用户线程会等待拷贝的完成,而异步 I/O则这个拷贝过程用户线程该干嘛可以去干吗,当内核拷贝完毕之后会“通知”用户线程。
要注意,不同场景下同一个名词意义可能不同。我这篇关于同步、异步、阻塞、非阻塞这几个概念是基于 I/O 场景下讲的。