同步异步与阻塞非阻塞这两组概念在 IO 场景下非常常见,由于他们在表现出来的效果上很相似,很容易造成混淆和困扰,要想理清楚这两组概念首先需要认识到这两组概念强调的是不同维度的事。
同步异步强调的是两个操作之间的顺序关系,两个操作之间是有序的还是无序的;
阻塞与非阻塞强调的是一个调用发起后调用发起方的行为,是被动等待还是主动获得执行权;
下面以 Python 代码为例介绍这几个概念。
同步关系与异步关系
因为同步异步强调的是两个操作之间的顺序关系,所以加上关系俩字更好理解和区分。
同步 "Synchronous" 这个词源自希腊语 "syn"(意为"一起")和 "chronos"(意为"时间"),它的字面意思是"在同一时间发生"。在通信和计算机领域中,“同步”则有两层含义,一个是"一起发生",另一个是"按顺序进行",这两层含义缺一不可,它意味着多个操作按照预定的顺序和时间协调进行,从而保持整体的一致性和协调性。
这里可以联想一下并发控制中为什么存在“同步互斥”这样的概念?目的就是为了协调多进程访问临界区时,必须等临界区中的 A 进程退出临界区后,B 进程才可以进入临界区执行,本质上是将并行(异步)关系变成了串行(同步)关系。
再回想一下 SQL 隔离级别中最高级别串行化 Serializable 是不是更能理解了?同样是将并行(异步)关系变成串行(同步)关系。
同步关系 (Synchronous)
同步指的是某个操作 A 必须等待前一个操作 B 完成之后才能开始,也就是说 A 在 B 完成之前不会启动。
也可以描述为 A sync before B,意味着操作 A 在操作 B 之后按顺序执行,并且 A 必须等待 B 完成后才开始。
说白了同步意味着 A 和 B 之间的执行有先后顺序关系,中国有句古话:先穿袜子再穿鞋,先当孙子再当爷,讲述的就是这个道理