在windows或者linux上面,网络编程相关资料总会提到阻塞模式,非阻塞模式,同步I/O,异步I/O。
不过很多人对这几个概念的理解并不清晰,有一定偏差,甚至是明显的错误的理解。
在windows平台的一些出版书籍中明确提到了阻塞,非阻塞,以及6个I/O模型,但对这些概念之间的关系没有明确说明,语焉不详。
其实在《Unix 网络编程》中,已经对这几个概念的区别和交集有明确界定。
Unix网络编程确定了5个I/O模型:
阻塞I/O模型
非阻塞I/O模型
I/O复用模型
信号驱动模型
异步I/O模型
并且明确了2个概念,一个输入操作分为2个阶段:1.等待数据准备好,2从内核到进程拷贝数据
POSIX关于同步I/O,异步I/O的定义:
同步I/O操作引起请求进程阻塞,知道I/O操作完成
异步I/O操作不引起进程阻塞
《unix网络编程》认为:前4个模型的第二个阶段基本相同,在数据从内核到调用者的缓冲区时,进程阻塞与recv或者其他调用,而异步I/O模型得到的通知的时候数据已经拷贝到缓冲区了,因此,前面4个模型都是同步I/O,只有第五个才是异步I/O
把这些概念套用到win平台的6个模型,阻塞模型,select模型,wsaasyncselect模型,wsaeventselect模型,显然属于同步I/O。而重叠模型和完成端口则属于异步I/O,因为后2个模型也是由内核自行把数据复制到用户的缓冲区的。
不过unix网络编程定义的5个I/O模型的概念也并不合理,个人认为并不存在非阻塞这样的模型,因为select ,epoll这些模型都可以使用阻塞或者非阻塞模式。相对来说,win平台对I/O模型的定义则要合理一点。
并且在windows网络编程中则专门提到,wsaasyncselect,wsaeventselect具有异步通知能力,重叠及完成端口具有异步数据传送的能力。
因此我们可以对2个平台的所有模型进行一个合理的分类
同步I/O
阻塞模型
同步I/O,异步通知
select,wsaasyncselect,wsaeventselect,epoll,kqueue
异步I/O
aio,重叠,完成端口