今天我们来聊一聊什么是同步,什么是异步,以及在编程中这两个极为重要的概念到底意味着什么。
这两个看上去很像,实际上也很像的词背后所代表的含义到底是什么呢?我们先从工作场景讲起。
譬如老板让你写一个功能,并什么都不做,坐在你身边直到你写完,这个场景就是所谓的同步。
譬如老板让你写一个功能,然后他去谈业务,你写完了告诉他完成了,这个场景就是所谓的同步。
为什么一般来说异步比同步高效呢?还是上面的例子,在同样的时间里,同步场景里,你完成了功能,老板啥都没做;在异步场景里,你完成了功能,老板谈成了业务。很明显异步比同步效率高。
一、同步调用
既然现在我们已经理解了同步与异步在场景下的意义(I hope so),那么对于程序员来说该怎样理解同步与异步呢?
我们先说同步调用,这是程序员最熟悉的场景。
一般的函数调用都是同步的,就像这样:
funcA() {
// 等待函数funcB执行完成
funcB();
// 继续接下来的流程
}
funcA调用funcB,那么在funcB执行完前,funcA中的后续代码都不会被执行,也就是说funcA必须等待funcB执行完成,就像这样:
从上图中我们可以看到,在funcB运行期间funcA什么都做不了,这就是典型的同步。
注意,一般来说,像这种同步调用,funcA和funcB是运行在同一个线程中的,这是最为常见的情况。
二、异步调用
有同步调用就有异步调用。
一般来说,异步调用总是和I/O操作等耗时较高的任务如影随形,像磁盘文件读写、网络数据的收发、数据库操作等。
我们还是以磁盘文件读取为例。
在read函数的同步调用方式下,文件读取完之前调用方是无法继续向前推进的,但如果read函数可以异步调用情况就不一样了。
假如read函数可以异步调用的话,即使文件还没有读取完成,read函数也可以立即返回。
read(file, buff);
// read函数立即返回
// 不会阻塞当前程序
就像这样:
可以看到,在异步这种调用方式下,调用方不会被阻塞,函数调用完成后可以立即执行接下来的程序。
这时异步的重点就在于调用方接下来的程序执行可以和文件读取同时进行,从上图中我们也能看出这一点,这就是异步的高效之处。
但是,请注意,异步调用对于程序员来说在理解上是一种负担,代码编写上更是一种负担,总的来说,上帝在为你打开一扇门的时候会适当的关上一扇窗户。
所谓鱼和熊掌不可兼得,具体在开发过程中选用同步调用还是异步调用还是要分情况来看。
|