个人BIO、NIO、AIO学习

网络上关于讲解三种通信方式的文章合起来看总有矛盾之处,看了好几篇都觉得不能理解,读的时候也知道了这三种通信涉及了很多linux OS方面的知识(我并不理解),所以基于大手子的资料,加深记忆,我只能做一些概念上的总结,其实我这个人比较相信书本的,尤其是外国的,所以参考的文章可能出错,不可尽信,有差错也希望大手子看到能提点我 

贴上一些参考的文章

1、如何深刻理解reactor和proactor?:https://www.zhihu.com/question/26943938

2、聊聊BIO,NIO和AIO (1):https://www.jianshu.com/p/ef418ccf2f7d 

3、Netty序章之BIO NIO AIO演变(Java代码实例):https://segmentfault.com/a/1190000012976683

 

怎样理解网络IO中的阻塞非阻塞与同步异步的区别?

这个很大程度决定了你的理解是错误还是正确

这里上下文限定是Linux环境下的 ,C语言为例

同步与异步:实际的IO读写(内核的缓冲区复制到进程缓冲区时)是否需要进程参与,需要操作系统调用的支持,这句话比较难理解看不懂可以看完下面两个知乎答案体会

阻塞与非阻塞:进程/线程发起的IO请求(比如read/recv函数)是否会被阻塞

via 必看:怎样理解阻塞非阻塞与同步异步的区别?大姚灵剑的回答——https://www.zhihu.com/question/19732473

               为什么NIO被称为同步非阻塞? 祖春雷回答——https://www.zhihu.com/question/56673416

 

Reactor、Proactor是什么?

两种基于IO复用的设计模式(关于IO复用可以看文章《聊聊BIO,NIO和AIO 》),Reactor需要select,poll,epoll,kqueue(按效率排序,操作系统层面的调用支持),Proactor需要iocp的支持(linux用epoll模拟异步),前者为同步IO,后者为异步IO,不太了解,既然是设计模式,抽象程度比较高,可以先放着。

以Java的 API 为例

BIO

Blocking IO,字面意思阻塞IO,比如用ServerSocket的accpet获取连接,不用想都是同步阻塞的,当拿到流对象时进行IO请求(read)时,如果没有数据到来,方法是阻塞的,且如果是阻塞IO的那么必定是同步IO(这句话看不懂可以先放着,同步表示,内核的缓冲区复制到进程缓冲区阶段发生在IO请求的执行过程中,如果看完了知乎的两个答案应该能理解),一般用线程池和连接绑定,线程太多又没有实际的数据到来,光维持连接线程都会爆炸,所以发展处NIO

NIO

Non-Blocking IO ,字面意思不阻塞IO,如何做到不阻塞?循环询问是否有没有数据到达,可以类比为锁里的tryLock方法,这样就可以算作非阻塞了,但这样很傻比,因为你需要不断地重复问一个线程同样的问题直到他有数据了,

所以延伸出IO复用机制,用一个监听复用器去轮询注册在其上的Socket Channel,并把数据和IO操作封装为事件,当有事件就绪时,再传递给线程执行我们的IO请求(read),这样可以做到几个线程的就可以管理很多的Socket,并且保证了当执行IO请求时,数据已经存在,线程并不会阻塞。

这里可以看到,IO操作不会阻塞,得益于 IO复用机制 把BIO的 IO阻塞时间成本 优化并提前至轮询阶段,并且NIO还是同步的,因为内核的缓冲区复制到进程缓冲区阶段仍发生在IO请求的执行过程中,轮询间隔和同步造成的一些费用仍然是个问题。

虽然不知道怎么解释,但可以这么理解,阻塞就一定同步,但不阻塞就有可能异步

AIO

Asynchronous IO,异步非阻塞IO,这里解决了内核的缓冲区复制到进程缓冲区的时间问题,当复制完成后才会通知线程进行处理,感觉像Ajax的回调函数,Java API AsynchronousSocketChannel和AsynchronousServerSocketChannel

这个感觉更复杂了,所以看个大概随便写了点应付面试

select、poll、epoll、kqueue、IOCP、Reactor、Proactor、NIO、AIO、netty有什么关系?

 select、poll、epoll、kqueue、IOCP是操作系统层面的网络模型

Reactor、Proactor软件框架层面的设计模式

NIO、AIO应该是根据以上两种材料,构建的软件框架模型

netty应该就是用上面的模型实现的框架库

猜你喜欢

转载自www.cnblogs.com/haon/p/11043260.html
今日推荐