前言
对阻塞/非阻塞和同步/异步的概念大家一定不陌生,平常多多少少都会接触,如某个异步的接口调用,一个异步的框架,但是如果真正的让你在面试时定义这个概念,可能就摸不着头脑了。
常见问题:
- 阻塞和非阻塞的区别?
- 同步和异步的区别?
- 非阻塞和异步一样吗?
- 五种I/O模式各自是什么类型?
- Java中的NIO/AIO是异步吗?
- Epoll是异步吗?
- …
对阻塞/非阻塞,同步/异步概念的理解绝非简单的几个买书或者约会的比喻就能解释清楚,这些比喻拿来应付外行还行,如果在面试时说,想想还是蛮尴尬的 (°ー°〃) ,
面试官: 请描述一下异步I/O系统调用。
我: 异步指定是我们现在不需要约会,而是在以后某个时间由你来通知我,然后进行约会。
面试官:。。。
那么应该从什么角度来回答这些问题,才能显得自己是一个聪明能干肯钻研的好后生呢?我得出以下结论:
- 明定义-----在什么层级上定义的概念
- 分角度-----从什么角度来比较
- 会延伸-----将面试往自己期待的方向引导
接下来,看如何理解上面三点!
先修知识
阻塞/非阻塞,异步同步的概念涉及的知识比较广,涉及如下几个需要了解的知识:
- Linux进程
1)进程切换
2)进程状态 - I/O
1)缓存I/O
2)网络I/O
下面只是大致介绍,但是每一点都是十分重要的内容
进程切换
上图,展示的是由进程P0切换到内核,再从内核切换到进程P1,最后再切换回来的流程图:
1)中断(interrupt) 或 系统调用(system call) 发生可以使得 CPU 的控制权会从当前进程转移到操作系统内核;
2)操作系统负责保存P0在CPU中的上下文(进程上下文,所有寄存器中的值,进程的状态,堆栈中的内容),保存到PCB0(进程控制块) 中;
3)从PCB1中取出进程P1的进程上下文,将CPU的控制权转移到进程P1,即可以执行P1的指令了。
注意:
我们讨论阻塞/非阻塞,同步/异步一般针对一个特定的系统调用(system call),例如对硬盘或者网络接口的读写,现在就知道,当我们发起一次read()
时,我们的进程将被切换到内核态,既然控制权不在调用read()
的进程了,那势必进程的状态会发生改变。
进程状态