1.linux的epoll

epoll 是Linux内核中的一种可扩展IO事件处理机制,最早在 Linux 2.5.44内核中引入,可被用于代替POSIX select 和 poll 系统调用,并且在具有大量应用程序请求时能够获得较好的性能( 此时被监视的文件描述符数目非常大,与旧的 select 和 poll 系统调用完成操作所需 O(n) 不同, epoll能在O(1)时间内完成操作,所以性能相当高),epoll 与 FreeBSD的kqueue类似,都向用户空间提供了自己的文件描述符来进行操作。

一、高效的epoll

epoll 是Linux下,高效的多路复用技术,也是Linux下高性能网络服务器的关键技术。 通过网络socket链接,把远程资源加载到本地内存中。如何来优化这个性能呢?

二、epoll提出原因

2.1.poll和select 相对之前的AIO有很大的提高,但是由于需要监视着“等待队列”与及“阻塞进程”,性能还是未完全释放。 这个时候CPU又被别的进程给抢走,上下文切换的性能又被消耗。

2.2.select 要进行遍历,才能感知到那个socket来了数据,因此select只能一个一个遍历,来唤醒每个socketChanel。

三、epoll原理

3.1 epoll监视多个socket, 改进了select维护等待队列和阻塞进程进一步改进。把这两步动作给拆分开来。

3.2 epoll_ctl 维护等待队列

3.3 epoll_wait 阻塞队列

四、eventpoll

4.1 调用epoll_create方法,另外会创建一个eventpoll对象。

4.2 eventpoll维护着就绪列表,如果有socket来数据,就把socket添加到就绪列表。

4.3 阻塞进程收到就绪列表的回调,既可以开始socket数据传输工作。

2.netty的epoll

使用Netty构建服务器时,需要指定parent线程池和child线程池,parent线程负责监听端口,一旦有连接接入,则注册到child线程池中的一个线程上,该连接的IO操作/任务都由该线程完成。 换句话说,一个线程会负责多个连接的IO操作,也就是多路复用。Netty底层是使用系统提供的select或者epoll来实现多路复用的。

先来科普下select/poll/epoll。

select/poll

服务端建立每个连接,相当于打开文件,会获得对应的文件描述符(fd),相同的源IP/源端口/目标IP/目标端口对应同一个fd。

select和poll是相似的,不一样的地方是,select是使用数组,有连接数限制,而poll使用链表,无连接数限制。

监听连接时,从用户层的角度看, (1)会构建3个fd数组,分别关注读/写/异常事件,设置超时时间,调用系统提供的select方法。 (2)调用select方法时,需要将fd数组传到内核态,等待部分fd就绪后,把fd数组(包含就绪状态)返回到用户态 (3)用户程序对fd数组进行遍历,处理就绪的fd (4)重新调用select方法。

可以看出不好的地方是(1)每次都要传入fd数组,返回整个fd数组,导致了大量在用户空间和内核空间的相互拷贝。 (2)用户程序仍需要遍历fd数组才能找出就绪的fd

从系统层的角度看,调用select方法时 (1)遍历fd数组,对于每个fd,调用其对应的poll方法(由设备对应的驱动程序实现),将fd所在线程加入等待队列,并且检查就绪状态,记录感兴趣的就绪状态。 (2)如果存在感兴趣的就绪状态,直接返回 (3)如果不存在感兴趣的就绪状态,进入休眠,等待fd就绪后,会唤醒等待队列中的线程 (4)被唤醒后,重复1-4的操作。

可以看出不好的地方是每次都需要检查所有fd。

epoll

epoll相对select改善了很多。 (1)在使用epoll时,首先会构建epoll对象。 (2)有连接接入时,会插入到epoll对象中,epoll对象里实际是一个红黑树+双向链表,fd插入到红黑树中,通过红黑树查找到是否重复 (3)一旦fd就绪,会触发回调把fd的插入到就绪链表中,并唤醒等待队列中的线程。 (4)调用epoll_wait方法时只需要检查就绪链表,如有则返回给用户程序,如没有进入等待队列。

由于epoll把fd管理起来,不需要每次都重复传入,而且只返回就绪的fd,因此减少了用户空间和内核空间的相互拷贝,在fd数量庞大的时候更加高效。

Netty可以选择使用不同的多路复用技术。

NioEventLoop

NioEventLoop底层会根据系统选择select或者epoll。如果是windows系统,则底层使用WindowsSelectorProvider(select)实现多路复用;如果是linux,则使用epoll

当为select模式,在NioEventLoop对应的Selector中会维护着newKeys,updateKeys,cancelledKeys,分别是新增的fd,更新fd的感兴趣状态,取消fd监听。每当连接接入,或者断连,都会调用NioEventLoop的注册/解除注册方法,更新这几个集合。(这里是JDK11的实现,在JDK8中则直接更新PollArrayWrapper)

NioEventLoop在运行的时候,会不断的监听注册的连接,核心逻辑在doSelect方法中,主要的几个操作是 (1)processUpdateQueue,将newKeys,updateKeys,cancelledKeys中的key更新到PollArrayWrapper中 (2)subSelector.poll(),这里实际是调用native方法,会将PollArrayWrapper的fd拷贝至readFds/writeFds/exceptFds,并监听这些fd。

private native int poll0(long pollAddress, int numfds,int[] readFds, int[] writeFds, int[] exceptFds, long timeout);
​

(3)updateSelectedKeys,遍历freadFds/writeFds/exceptFds,将就绪的fd存储到selectedKey中

当存在fd就绪后,doSelect方法返回,应用程序可以遍历selectedKey进行处理。

EpollEventLoop

EpollEventLoop底层使用epoll实现多路复用。

EpollEventLoop中会初始化epollFd、eventFd、timerFd。

  • epollFd是调用系统方法生成的epoll对象,后续会使用其管理所有需要监听的fd

  • eventFd是用于线程通讯,程序会把eventFd添加到epollFd中,监听eventFd,一旦eventFd有操作,则会唤醒调用epoll_wait的线程。

  • timerFd是用于计时,同样的监听timerFd,一旦时间到达,则会唤醒调用epoll_wait的线程。

每当连接接入或者断连,都会调用epoll_ctl_add/epoll_ctl_del方法来操作epoll对象。

在EpollEventLoop的run方法中,会调用epoll_wait来监听所有fd,一旦有fd就绪,会拷贝至EpollEventArray中,应用程序遍历EpollEventArray处理所有就绪事件。

netty的epoll和linux的epoll是如何实现的相关推荐

  1. 深入理解 Linux 的 epoll 机制

    坚持思考,就会很酷 在 Linux 系统之中有一个核心武器:epoll 池,在高并发的,高吞吐的 IO 系统中常常见到 epoll 的身影. IO 多路复用 在 Go 里最核心的是 Goroutine ...

  2. Handler消息机制(一):Linux的epoll机制

    在linux 没有实现epoll事件驱动机制之前,我们一般选择用select或者poll等IO多路复用的方法来实现并发服务程序.在linux新的内核中,有了一种替换它的机制,就是epoll. sele ...

  3. linux下epoll如何实现高效处理

    linux下epoll如何实现高效处理 作者 digoal 日期 2016-11-10 标签 Linux , 内核 , epoll , 网络编程 , 高并发 背景 本文转自 http://www.cn ...

  4. 使用Epoll 在 Linux 上开发高性能应用服务器

    epoll是Linux提供一种多路复用的技术,类似各个平台都支持的select,只是epoll在内核的实现做了更多地优化,可以支持比select更多的文件描述符,当然也支持 socket这种网络的文件 ...

  5. linux socket epoll

    什么是epoll epoll是什么?按照man手册的说法:是为处理大批量句柄而作了改进的poll.当然,这不是2.6内核才有的,它是在2.5.44内核中被引进的(epoll(4) is a new A ...

  6. Windows 平台下面的IOCP技术 Linux下面Epoll 还有FreeBSD下面Kqueue的应用了。跨平台库行业里面最出名的莫过于ACE、ASIO(Boos公司)两大支持库支持IOCP

    http://wenku.baidu.com/view/4117460502020740be1e9b3c.html 游戏服务器集群 自从2003年开发VOIP Radius Server以及修改Gnu ...

  7. linux中select和epoll原理,Linux下selectpollepoll的实现原理(一)

    最近简单看了一把 linux-3.10.25 kernel中select/poll/epoll这个几个IO事件检测API的实现.此处做一些记录. 其基本的原理是相同的,流程如下 先依次调用fd对应的s ...

  8. linux中epoll原理,Linux下selectpollepoll的实现原理(一)

    最近简单看了一把 linux-3.10.25 kernel中select/poll/epoll这个几个IO事件检测API的实现.此处做一些记录. 其基本的原理是相同的,流程如下 先依次调用fd对应的s ...

  9. linux中epoll原理,linux epoll epoll的原理

    epoll原理简述:epoll = 一颗红黑树 + 一张准备就绪句柄链表 + 少量的内核cache select/poll 每次调用时都要传递你所要监控的所有socket给select/poll系统调 ...

最新文章

  1. Spread for Windows Forms高级主题(3)---单元格的编辑模式
  2. reporting services 导出pdf格式优化
  3. opencv图像识别
  4. Java 在 CMD 环境下编译
  5. uni-app开发微信小程序之获取当前地址
  6. C# 中的 null 包容运算符 “!” —— 概念、由来、用法和注意事项
  7. 转载 | pymysql.err.InterfaceError: (0, ‘‘)解决办法
  8. php 去掉多维数组的键名,去除多维数组的最外层key 保留值
  9. 如何将多个excel表格合并成一个_如何将一个视频分割成多个片段
  10. k8s核心技术-Pod(调度策略)_影响Pod调度(节点亲和性)---K8S_Google工作笔记0026
  11. linux进行硬盘分区挂载-了解系统,最更好的开发
  12. MongoDB更新文档(非常详细,不要错过~)
  13. 网上偶看一文,有感。特贴在下面。
  14. OpenJDK8在LINUX上,输入法候选框无法正确定位
  15. 东鹏特饮占据市场第二的背后:数据让我们比谁都了解消费者!
  16. netperf-2.7.0 交叉编译
  17. 增值税发票开票软件卷票打印错位配置修正指南
  18. 决战618!摩杜云爆款秒杀,最低一年3.3元起
  19. 切入点表达式的写法详解
  20. 【yum】yum “Status code: 404 for http:”错误

热门文章

  1. 冒泡排序法(C语言实现)
  2. 【C语言函数递归】递归计算最大公约数
  3. Excel中F4键的作用
  4. 交通 流量 时间序列预测,神经网络 机器学习 BPNN
  5. WebSestalt,好用的富集分析工具,介绍及使用教程
  6. JDBC简介及原理和使用介绍
  7. 初识华为云数据库GaussDB(for Cassandra
  8. Jmeter中唯一值-UUID取值(截取指定长度、去除“-”)
  9. unwinding now org.apache.cxf.interceptor.Fault: Index: 1, Size: 1
  10. 笔记:计算机公共基础知识学习内容(总)——全国计算机二级考试