这是面试中的高频问题,应该是每一个程序员都应该了解的。
同步:官方的解释是发起一个功能调用,在没有得到结果之前,该调用就不返回。同步就是协同步调,按预定的先后次序进行运行,
同步这个词很多人以为是同时进行,恰恰相反
注意,同步就是多个功能调用的执行一定是有先后顺序的
其实我们大部分使用的函数都是同步的,一定要等到实现函数功能后再返回结果,然后执行后面的函数。比如wait函数,大部分后端语言都有这个函数,在多进程/线程/协程中,可以监听子进程/线程/协程的返回状态,如果子程没有结束,在wait函数这就一直阻塞。
同步不针对一个函数,还可以是一段程序
比如多线程/协程中,操作共享变量需要加锁,对共享变量的读写操作是原子操作,是不能被打断的,多个线程对变量的访问是串行的
异步:进行一个功能调用时,不需要等到功能执行完,得到结果再返回,异步是马上返回的,也就是不会阻塞
例如,多线程/协程本身就实现了异步,我们要执行一个函数,但是,这个函数执行时间比较长,我们不想这个函数影响我们后面程序的执行,怎么办呢?再开一个线程就解决了,也就是实现异步了,主线程不等你了,你自己开个线程去玩吧。在多线程中,访问共享变量一定有同步问题,也就是异步的时候,有一小段是同步的,两个敌人也有合作的时候,是吧!同步问题上面已经提到了,不再多说
从上面来看,好像同步和阻塞就是一个意思,其实还是有区别的
同步异步解决的是函数执行顺序的问题,而阻塞非阻塞就是指的会不会卡住,等锁 或者 睡眠 或调用时间过长 或 io阻塞,都会导致程序阻塞。
同步一定阻塞吗?
不一定,例如下面程序,这三行代码就是同步的,并没有阻塞。当然大部分情况下,我们说的同步是阻塞的
int a
a = 3
a = 4
异步一定非阻塞吗?
其实不一定,比如我们要实现主协程在子协程退出后马上打印 hello world,主协程就要使用wait(go语言)或join(C语言)函数等待,主线程不就阻塞了吗?