同步-异步-阻塞-非阻塞详解
Table of Contents
1 概述
同步和异步是一种消息通信机制 (synchronous communication/ asynchronous communication),关注点在于 被调用者返回 和 结果返回 之间的关系, 描述对象是被调用对象的行为。
- 同步(Synchronous):发出调用,在没有得到结果前,调用不返回。
- 异步( Asynchronous):发出调用,直接返回,不关心是否返回结果。异步可以通过 回调 通知调用者结果。
阻塞和非阻塞是一种业务流程处理方式。关注点在于调用发生时 调用者状态 和 被调用着返回结果 之间的关系。 描述的是等待结果时候调用者的状态 。 此时结果可能是同步返回的,也能是异步返回。
- 阻塞( Blocking ):在结果返回之前,当前流程被挂起,后续代码只有在结果返回后才能执行。
- 非阻塞( Nonblocking):在不能立刻获取结果前,该调用不会阻塞当前进程。
用去书店借书来举例说明:
- 同步阻塞:打电话问老板有没有某书(调用),老板说查一下,让你别挂电话(同步),你一直等待老板给你结果,什么事也不做(阻塞)。
同步非阻塞:打电话问老板有没有某书(调用),老板说查一下,让你别挂电话(同步),等电话的过程中你还一边嗑瓜子(非阻塞)。
实际编程中,通过线程实现进程的同步非阻塞,通过协程实现线程的同步非阻塞。
- 异步阻塞:打电话问老板有没有某书(调用),老板说你先挂电话,有了结果通知你(异步),你挂了电话后(结束调用), 除了等老板电话通知结果,什么事情也不做(阻塞)。
- 异步非阻塞:打电话问老板有没有某书(调用),老板说你先挂电话,有了结果通知你(异步),你挂电话后(结束调用),一遍等电话,一遍嗑瓜子。(非阻塞)
要清楚理解这四个概念,首要要名表的是,同步异步/阻塞非阻塞描述对象是不同的,这点我比较同意 怎样理解阻塞非阻塞与同步异步的区别? - 灵剑的回答 - 知乎 的说法。
2 Unix系统IO模型
《UNIX网络编程:卷一》书中提及了5 种类UNIX下可用的I/O模型:
- 阻塞式I/O
- 非阻塞式I/O
- I/O复用(select,poll,epoll…)
- 信号驱动式I/O(SIGIO)
- 异步I/O(POSIX的aio_系列函数)
正如知乎上 怎样理解阻塞非阻塞与同步异步的区别? - 陈硕的回答 - 知乎 所说,“在处理IO的时候,阻塞和非阻塞都是同步IO”,因为它们结果都是在调用结束的时候返回的。
只有使用了特殊API才是异步IO,例如linux的 aio和windows的 IOCP。