错误的四个象限分类
同步是需要主动等待消息通知,而异步则是被动接收消息通知,通过回调、通知、状态等方式来被动获取消息。IO多路复用在阻塞到select阶段时,用户进程是主动等待并调用select函数获取数据就绪状态消息,并且其进程状态为阻塞。所以,把IO多路复用归为同步阻塞模式。
I/O多路复用就是通过一种机制,一个进程可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作。但select,pselect,poll,epoll本质上都是同步I/O,因为他们都需要在读写事件就绪后自己负责进行读写,也就是说这个读写过程是阻塞的,而异步I/O则无需自己负责进行读写,异步I/O的实现会负责把数据从内核拷贝到用户空间。
正统的五种unix-io模型
1.Blocking IO Model
2.Unblocking IO Model
3.IO Multiplexing Model:SELECT/POLL/EPOLL/KQUEUE
4.Signals (SIGIO)
5.Asynchronous I/O -POSIX AIO
图片来自netty权威指南
小结
之前所述的blocking IO,non-blocking IO,IO multiplexing都属于synchronous IO。
synchronous IO:当kernel中数据准备好的时候,recvfrom会将数据从kernel拷贝到用户内存中,这个时候进程是被block了,在这段时间内,进程是被block的。
asynchronous IO:则不一样,当进程发起IO 操作之后,就直接返回再也不理睬了,直到kernel发送一个信号,告诉进程说IO完成。在这整个过程中,进程完全没有被block。
一个恰当的比喻(没有第四种)
最后,再举几个不是很恰当的例子来说明这四个IO Model:
有A,B,C,D四个人在钓鱼:
blocking IO: A用的是最老式的鱼竿,所以呢,得一直守着,等到鱼上钩了再拉杆;
nonblocking IO: B的鱼竿有个功能,能够显示是否有鱼上钩,所以呢,B就和旁边的MM聊天,隔会再看看有没有鱼上钩,有的话就迅速拉杆;
IO multiplexing: C用的鱼竿和B差不多,但他想了一个好办法,就是同时放好几根鱼竿,然后守在旁边,一旦有显示说鱼上钩了,它就将对应的鱼竿拉起来;
asynchronous IO: D是个有钱人,干脆雇了一个人帮他钓鱼,一旦那个人把鱼钓上来了,就给D发个短信。
参考:
https://blog.csdn.net/historyasamirror/article/details/5778378
https://www.zhihu.com/question/19732473
https://www.ibm.com/developerworks/cn/linux/l-async/index.html