詹学伟
詹学伟
Published on 2024-04-27 / 6 Visits
0
0

如何理解阻塞、非阻塞与同步、异步的区别?

同步与异步

同步与异步关注的是消息通信机制

  • 所谓同步,就是在发出一个调用时,在没有得到结果之前,该调用就不返回。但是一旦调用返回,就得到返回值了。换句话说,就是由调用者主动等待这个调用的结果。

  • 异步则是相反,调用在发出之后,这个调用就直接返回了,所以就没有返回结果。换句话说,当一个异步过程调用发出后,调用者不会立刻得到结果。而是在调用发出之后,被调用者通过“状态”“通知”“回调”三种途径通知调用者。

可以使用哪一种途径依赖于被调用者的实现,除非被调用者提供多种选择,否则不受调用者控制。

  • 如果被调用者用状态来通知,那么调用者就需要每隔一定时间检查一次,效率就很低。

  • 如果使用通知和回调的方式,效率则很高。因为被调用者几乎不需要做额外的操作。

举个例子:

你打电话问书店老板有没有《高效演讲》这本书。

如果是同步通信机制,书店老板会说,你稍等,”我查一下",然后开始查啊查,等查好了(可能是5秒,也可能是一天)告诉你结果(返回结果)。

异步通信机制,书店老板直接告诉你我查一下啊,查好了打电话给你,然后直接挂电话了(不返回结果)。然后查好了,他会主动打电话给你。在这里老板通过“回电”这种方式来回调。

阻塞与非阻塞

阻塞和非阻塞关注的是程序在等待调用结果(消息,返回值)时的状态。

  • 阻塞调用是指调用结果返回之前,当前线程会被挂起。调用线程只有在得到结果之后才会返回。

  • 非阻塞调用指在不能立刻得到结果之前,该调用不会阻塞当前线程。

接着上面的例子:

打电话问书店老板有没有《高效演讲》这本书,

  • 如果是阻塞式调用,你会一直把自己“挂起”,直到得到这本书有没有的结果。

  • 如果是非阻塞式调用,你不管老板有没有告诉你,你自己先一边去玩了(先去干点别的,不用傻等), 当然你也要偶尔过几分钟检查一下老板有没有返回结果。

回调函数

前面提到,回调是异步调用的一种实现方式。那么什么是回调函数呢?

  • 概念

回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。

回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。

  • 举个例子

概念不是太好理解,我们举个例子。

沿用上面买书的例子,你的电话号码就叫回调函数,你把电话留给书店老板就叫登记回调函数,书店老板查好了叫做触发了回调关联的事件,老板给你打电话叫做调用回调函数。你接电话叫做响应回调事件。


Comment