ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

再次针对BIO NIO Reactor模式进行总结(项目迭代)

2021-08-28 08:32:13  阅读:145  来源: 互联网

标签:BIO NIO epoll 线程 IO fd Reactor


Unix下的IO模型

阻塞IO,非阻塞IO,异步IO,IO多路复用,信号驱动;Linux下的IO多路复用函数为select和epoll;Java层面的IO多路复用为NIO,NIO在Linux系统上依靠epoll来实现,Java层面阻塞IO为BIO,非阻塞IO好像没有?异步IO为AIO

BIO

BIO的accept和read函数都是阻塞式的,这意味着如果没有客户端连接/客户端连接了却并未发内容的时候,该线程必须放弃cpu时间,在原地阻塞式地等待。那么如果需要实现并发,就必须在多线程的环境下,多线程必然涉及线程的创建和销毁,这是重量级的操作,会大量消耗资源,如果使用线程池可以避免这部分的资源浪费,但只是治标不治本的解决方法,因为阻塞式的等待本质上就是在浪费服务器的资源

NIO

为了使得单线程环境下也可以实现并发的操作,提高服务端的处理效率,JDK1.4 之后出现了NIO,实际上就是IO多路复用。NIO最重要的一点在多了ServerSocketChannel这样一个api,使得NIO的read方法和accept方法可以是非阻塞式的。但是直接转化为非阻塞式会有问题,例如socket的丢失,c1与Server连接后,c2需要与Server连接,因为c1没有保存,所以可能产生socket的丢失。为了应对这一情况,NIO使用了Selector,每当有一个新的客户端连接时,socket就会注册在Selector上,并得到一个SelectionKey,之后会有一个单独的线程不断对Selector进行轮询遍历,当需要读取数据时,就会从buffer里面读取。这样就实现了单线程环境下的并发操作。

AIO

异步IO,基于回调机制实现,用的不多,Why?

对比NIO,netty为什么更高性能

  1. Reactor模式的实现
  2. 零拷贝:
  3. 使用native方法(jni)
  4. netty默认采用主从Reactor模式,默认线程数为CPU内核的2倍

Reactor

我其实觉得有点像NIO+线程池;别的博客给的定义是IO多路复用监听事件,收到事件后,根据事件的类型发送给某个线程。主要有Reactor,Acceptor,Handler三个对象

然后没提现出封装的特性啊。。

单线程Reactor

  1. 这个跟NIO其实就很像了啦,基于轮询,有活跃的事件进行dispatch,然后如果是连接的任务就分发给accept,如果是处理读/写任务就分发的handler
  2. 缺点是Handler处理业务的时候,整个线程无法accept新的连接,其实也是NIO的缺点

多线程Reactor

前面还是一样,Reactor负责监听事件,收到事件后分发,如果是建立连接,分发给Acceptor,如果是读写事件,则发给Handler,但Handler不进行业务的处理,只负责读取数据,读取后发送给子线程中的Processor来处理。

这里有个问题是,子线程完成任务之后,要把结果传递给主线程,所以这里涉及到加锁

多线程主从Reactor

主Reactor负责监控连接建立事件,从Reactor负责相应事件的工作

Preactor

select 和 epoll

相同点

都是IO多路复用机制(同步),一旦某个描述符就绪,都能通知程序进行相应的读写

select

  1. 相对来说连接数较小,因为fd_set函数为1024或者2048
  2. 它将已连接的socket放到一个fd。然后拷贝到内核中,内核会通过遍历fd来检查到新的事件,并标记为可读or可写,然后在把整个fd集合拷贝回用户态,用户态再遍历一次,找到被标记的fd并处理
  3. poll和select的区别就是突破fd的限制,其余没有太大区别,无法适应并发的场景。

epoll的三个函数

epoll_create() 获得epoll句柄 open一个selector
epoll_ctl() 管理epoll内部的fd register的过程
epoll_wait()监听epoll内所有的fd,返回一个存放活跃fd的链表 selector.select();(把活跃的挑出来)

LT和ET

  1. 水平触发:fd就绪时触发通知,用户程序没有一次性读完的话,下次还会发出信号进行通知
  2. 边缘触发:仅fd就绪触发一次通知,之后不会再通知
  3. ET高效;两者最大的区别在于,数据没有读完的时候,内核是否会一直通知

标签:BIO,NIO,epoll,线程,IO,fd,Reactor
来源: https://www.cnblogs.com/donkeyAndConcise/p/15195862.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有