最近研究Nginx的时候知道了Nginx工作进程是异步非阻塞的方式,就对同步和异步、阻塞和非阻塞的区别产生了困惑,最后在segmentfault上看到了一篇简洁明了的解释很好。
转载自:https://segmentfault.com/a/1190000004240246
同步和异步,阻塞和非阻塞,这两组概念出现在IO操作中常常让人混淆不清。这里根据自己看到的,想到的,整理下自己的理解,权当交流。
IO操作其实可以分成两个步骤,请求IO操作和执行IO操作。一般的IO调用过程是这样的:发起IO操作的请求,执行IO操作,得到IO操作的结果,将结果返回给IO操作请求。
同步和异步
同步和异步是一种通信机制,涉及到调用方和被调用方,关注的是IO操作的执行过程及结果的返回方式,不同点在于双方在这两个方面的行为方式。
如果调用方需要保持等待直到IO操作完成进而通过返回获得结果,则是同步的;如果调用方在IO操作的执行过程中不需要保持等待,而是在操作完成后被动的接受(通过消息或回调)被调用方推送的结果,则是异步的。
同步和异步,适合描述执行IO操作的情境。
阻塞和非阻塞
阻塞和非阻塞是一种调用机制,只涉及到调用方,关注的是IO操作的执行状态,不同点在于请求IO操作后,针对IO操作的状态,调用方的行为方式。
如果调用方等待IO操作完成后返回,则是阻塞的;如果调用方不需要等待IO操作完成就立即返回,则是非阻塞的,非阻塞的情况下,常常需要多次调用去check,才能获得IO操作的结果。
阻塞和非阻塞,适合描述发起IO操作请求的情境。
阻塞与非阻塞,和同步异步无关,可以阻塞等待同步执行过程完成,也可以阻塞等待异步执行过程完成。根据以上理解,同步和异步,阻塞和非阻塞,是可以互相组合的。
同步阻塞
调用者发起IO操作请求,等待IO操作完成再返回。IO操作的过程需要等待,操作执行完成后返回结果。
同步非阻塞
调用者发起IO操作请求,询问IO操作的状态,如果未完成,则立即返回;如果完成,则返回结果。IO操作的过程需要等待执行完成才返回结果。
异步阻塞
调用者发起IO操作请求,等待IO操作完成再返回。IO操作的过程不需要等待,操作完成后通过通知或回调获得结果。
异步非阻塞
调用者发起IO操作请求,询问IO操作的状态,如果未完成,则立即返回;如果完成,则返回结果。IO操作的过程不需要等待,操作完成后通过通知或回调获得结果。