同步与异步
同步和异步关注的是消息通信机制。
所谓同步,就是在发出一个调用时,在没有得到结果之前,该调用就不返回。但是一旦调用返回,就得到返回值了。换句话说,同步就是由调用者主动等待这个调用的结果。
而异步则是相反,调用在发出之后,这个调用就直接返回了,调用者不会立刻得到结果。而是在调用发出后,被调用者通过状态、通知来告知调用者,或通过回调函数处理这个调用。
举个例子,你打电话给书店老板询问一本书,老板查了 1 分钟然后告诉了你这本书有货,这是同步。如果老板接到电话说我查到了再给你回电,这就是异步。
如果说老板在查询你的请求的同时又有别人打书店的另一台电话来查询,这也不算是异步,这是并行。网络编程中的同步异步仅是对同一个描述符(电话)而言,同步保证对这个描述符的操作是有序的(先查《呼啸山庄》,得到《呼啸山庄》的信息;后查《简爱》,得到《简爱》的信息),而异步有可能你第二次请求的先得到回答(先收到《简爱》的信息)。但都是反馈给你一个人的,和这期间有没有为别人查书籍无关。
阻塞与非阻塞
阻塞和非阻塞关注的是程序在等待调用结果时的状态。
阻塞调用是指调用结果返回之前,当前线程会被挂起。
非阻塞调用虽不能立刻得到结果,但该调用不会阻塞当前线程。过段时间再来询问之前的调用是否完成。这样的过程其实也叫轮询。
还是上面打电话的例子,如果是阻塞式调用,你会一直把自己“挂起”,直到得到这本书有没有的结果,如果是非阻塞式调用,不管老板是 1 分钟过后告诉你,还是等他查到了给你回电,你自己先去做别的事了,当然你也要偶尔 check 一下老板的状态。在这里阻塞与非阻塞与是否同步异步无关。跟老板通过什么方式回答你无关。
异步、同步阻塞与同步非阻塞
首先,异步就是异步,只有同步才有阻塞和非阻塞之分。看上去同步非阻塞比同步阻塞要好,但在活跃连接占比少的情况下,CPU 可能消耗更多的时间在轮询上,反而降低效率。I/O 的实现方式只要读写(收发)双方协商好(其实就是自己设计了一个简单的协议)就 OK 了。
异步是 I/O 最理想的模型,CPU 有必要时才参与,数据准备好了就通过回调函数通知应用程序。
网友评论