最近在看高并发的相关内容时,看到网络IO,认为要理解好高并发,要先理解好网络IO模型。在查看相关资料的同时,提到了同步、异步和阻塞、非阻塞的各种答案。在此想总结一下自己的理解。可以去知乎搜下,有很多好的回答。
一 同步、异步
有人说到,同步和异步是从消息通信机制来看的,A 请求 B,如果A 需要等B的应答,则是同步;如果A不需要等B的应答,直接处理其他事情,则是异步。这样看起来也没什么问题。但是也有另外一种解释,就是两个事物的协同,或者两个事情的执行顺序是否是顺序执行的,还是可以并行执行的。
1)从编程(业务代码)层面,我们时常会用到异步方法,直接调用,不需要理会结果,就继续处理其他事情了。和上面提到的解释比较吻合。
2)从IO操作层面,IO操作有俩件事情,(发送IO请求->得到IO结果),如果总是按这个有序序列进行就是同步IO,反之是异步IO。
二 阻塞 和 非阻塞
通俗一点说,就是我们碰到一个障碍的时候,根据我们的状态来判断是非阻塞。如果我们要等待,则是阻塞,如果不等待,去干其他事情了,则是非阻塞。即阻塞和非阻塞是从程序等待状态来判断的。
1)从编程(业务代码)层面,这个层面已经没有讨论阻塞和非阻塞的必要了,和同步、异步已经有点趋同了。
2)从IO操作层面,阻塞和非阻塞更多的是在讨论IO.在等待数据的过程中如果继续等待则是阻塞,如果不等待,而是隔三差五地来问是否准备好了,则是非阻塞。
三 IO模型
在Unix的相关书籍里,定义了IO的五种模型:
1) 阻塞IO: 在等待数据和拷贝数据两个阶段都被block住了(挂起)
2)非阻塞IO: 在等待数据阶段没有被block住,但是需要自己不断地来检查是否可读。但在拷贝数据地时候也被block住了。其实只是把阻塞的点放后了,但是非阻塞IO的定义就是这样,并不是它整个IO过程都是都可以做到非阻塞。
3)IO多路复用:这个其实也是阻塞的,只是对于用户进程,它没有被block住,而是有人来代替它监视socket.多路复用在于可以管理多个socket,轮询每个socket,看是否准备好数据。从这个角度看已经有些异步概念了。现在很多高并发的网络框架用的就是这个模型。宣称是异步网络IO.
4)信号驱动:不要监视socket了,被动等待信号通知
5)异步IO:发送IO请求后,不需要等了,内核会把数据准备好,要做的就是等内核通知,然后处理数据。这才是真正的异步IO,发送IO请求->得到IO结果并不是顺序执行的。
在网络上很多人将同步、异步和阻塞、非阻塞两两组合,其实对于IO来说,这种两两组合是不适合的。你真的将这种概念硬是套在上面的话,很容易陷入困惑中。 有人将IO多路复用称为异步阻塞,但是这个异步有待商讨,如果从IO层面,根本没有异步阻塞IO一说,异步就是异步,就只有异步IO,异步IO就是不阻塞的。但是如果从用户线程角度看,也是有一点点异步了,毕竟委托了别人看管了。
参考:
五种IO模型
https://www.cnblogs.com/findumars/p/6361627.html
关于同步、异步和阻塞、非阻塞的理解
https://www.cnblogs.com/Anker/p/5965654.html