在做网络编程的时候,我们会经常碰到阻塞(Blocking)与非阻塞(Non-Blocking)、同步(Synchronous)与异步(Asynchronous)的概念。这两组概念很相近,容易混淆。

阻塞和非阻塞是用来描述I/O操作的:在执行 I/O操作时,如果数据没有准备好,阻塞模式下会一直等待直到准备好或者超时,非阻塞模式下会立即返回。

同步与异步是用来描述消息传递方式:同步模式下,接收方需要不断地主动向发送方查询消息;异步模式下,发送方会主动将消息送给接收方。

本质上两组概念是没有关联的,不过我们会经常看到异步非阻塞的词语,这是因为在实际I/O处理时都有应用场景。处理I/O操作时,需要及时知道I/O状态及操作结果等消息。在Server端,通常会用异步的消息传递方式及非阻塞I/O以提高并发吞吐效率。

在这里先不去探讨类似epoll, libevent等技术细节。下面,苦李通过几个生动的小例子来加深一下理解。 小明高考完了,在家里等待录取通知书。

场景一(同步):

小明:“Hi,张大爷,我的通知书到了吗?” 张大爷:“没有” 小明玩了1个小时游戏后,又打电话:“Hi,张大爷,我的通知书到了吗?” 张大爷:“没有” 10个小时后… 小明:“Hi,张大爷,我的通知书到了吗?” 张大爷:“到了,快来取吧”

注:同步模式下,好处是主动获取消息,顺序的处理流程对我们的大脑比较友好,缺点是不断查询导致效率低,查询间隔过大会导致不能及时收到消息。

场景二(异步):

小明:“Hi,张大爷,通知书到了的话,请拨打我的电话138xxx” 张大爷:“好” 玩了10个小时游戏后小明突然接到张大爷的电话 张大爷:“通知书到了,快来取吧”

注:异步模式下,好处是有消息会及时被通知到,缺点是当前的任务可能会被打断。小明收到通知后,去传达室取通知书。

场景三(阻塞):

小明:“Hi,张大爷,我来取通知书” 张大爷:“还没有找到,你等我再找一找” 小明说:“好,我等一下,10分钟找不到我先去商场了,下次再来取” 10分钟后,张大爷还没有找到,于是对小明说:“不好意思,木有找到”

注:阻塞模式下,好处是确保等待结果,缺点是在此期间不能做别的事情,除非设定的超市时间已到。

场景四(非阻塞):

小明:“Hi,张大爷,我来取通知书” 张大爷:“没有看见,下次再来取” 小明出去玩了1个小时回来:“Hi,张大爷,我来取通知书” 张大爷:“没有看见,下次再来取” 小明又出去玩了1个小时回来:“Hi,张大爷,我来取通知书” 张大爷:“在这里,给你吧”

注:非阻塞模式下,好处是每次都会立即响应返回,缺点是需要不断询问。

标签: 程序员, 编程, 基础概念