按照《Unix网络编程》的划分,IO模型可以分为:阻塞IO、非阻塞IO、IO复用、信号驱动IO和异步IO。
按照POSIX标准来划分只分为两类:同步IO和异步IO。
如何区分呢?
首先一个IO操作(read/write系统调用)其实分成了两个步骤:1、发起IO请求;2、实际的IO读写(内核态与用户态的数据拷贝)
阻塞IO和非阻塞IO的区别在于第一步,发起IO请求的进程是否会被阻塞,如果阻塞直到IO操作完成才返回那么就是传统的阻塞IO,如果不阻塞,那么就是非阻塞IO。
同步IO和异步IO的区别就在于第二步,实际的IO读写(内核态与用户态的数据拷贝)是否需要进程参与,如果需要进程参与则是同步IO,如果不需要进程参与就是异步IO。
如果实际的IO读写需要请求进程参与,那么就是同步IO。因此阻塞IO、非阻塞IO、IO复用、信号驱动IO都是同步IO。
在编程上,这种非阻塞IO一般都采用IO状态事件+回调方法的方式来处理IO操作。
如果是同步IO,则状态事件为读写就绪。此时的数据仍在内核态中,但是已经准备就绪,可以进行IO读写操作。
如果是异步IO,则状态事件为读写完成。此时的数据已经存在于应用进程的地址空间(用户态)中。
以上全是和IO相关的同步异步。
另外在编程的方法调用上也存在同步调用和异步调用的说法。就拿RPC来说吧:
如果同步调用,则调用的结果会在本次调用后返回。
如果异步调用,则调用的结果不会直接返回。会返回一个Future或者Promise对象来供调用方主动/被动的获取本次调用的结果。