linux之epoll工作原理学习笔记

本文详细介绍了Linux内核中的epoll模型,包括epoll_create、epoll_ctl、epoll_wait的处理流程。epoll通过红黑树高效管理文件描述符,支持高并发IO处理。当数据到来时,内核会触发回调函数,将就绪事件放入就绪队列,唤醒等待的进程。epoll模型优化了系统在高负载情况下的性能和稳定性。
摘要由CSDN通过智能技术生成

1.epoll特点

epoll是一种高效的多路IO服用模型,目前好多框架底层都使用的是该模型,其特点是高性能,并且能支持高并发量的io处理的特点。该模型底层使用红黑树存储监听的文件描述符,且支持多并发连接的处理能力,从而让系统更加高效稳定的运行提供服务。

2.epoll创建及其运行时内核相关的处理流程。

2.1 epoll_create方法

    epoll_create调用的时候,内核中会创建一个struct eventpoll内核对象,并把当前结构关联到当前进程已打开的文件列表中。如下图各个内核结构&结构间的关联关系:

  struct eventpoll: 内核路径:fs/eventpoll.c

   

 eventpoll结构关联当前进程的文件列表:

 注:上图中对应的从task_file结构的路径include/linux/sched.h,相关结构根据区嵌套追踪即可查看。

上图拆解:

        当前进程调用epoll_create方法后,内核中会创建一个eventpoll结构,并将该结构关联到当前进程的文件列表中。eventpoll结构中,会创建epollwait的等待队列wq,就绪队列rdllist,并且会初始化上图中红黑树的rbr的根节点进行初始化等操作。

2.2 epoll_ctl方法

 调用epoll-ctl方法目的是将当前的socket添加到eventpoll结构中的红黑树结构中,并让epoll进行管理。当有数据来时,再进行对应数据处理。

 调用epoll_ctl时,系统内核都进行了那些操作呢?具体的操作有如下几个步骤:

  a.内核中会创建一个epitem结构,并进行其成员相关的初始化处理.其结构如下图:

  b.如果没有数据到来,将等待事件添加到socket的等待队列中,并注册一个回调函数ep_poll_callback.

  c.将eptiem结构插入到eventpoll结构管理的红黑树结构中。

  如下,epitem结构示意图:

  

   调用epoll_ctl方法后内核结构关联图图:

  

上图流程: 

        当调用epoll_ctl方法后,内核会先创建一个epitem结构进行初始化,实质上将对应的进程的socket跟文件对象地址存储至epitem结构中,并将自身内部的ep指针指向所属的eventpoll结构,表示自己数据当前这个eventpoll结构。再者会创建一个socket的等待队列结构元素,(自己起名sk_item代替,后续都是用该名称),其base指针指向之前创建的epitem结构,并且注册一个回调函数ep_poll_callback,最后将sk_item元素插入到socket的等待队列中。最后将epitem结构元素插入到eventpoll结构的rbr红黑树结构中进行管理。

2.3 epoll_wait方法

  epoll_wait调用该方法,内核中处理先判断eventpoll结构上的就绪描述符队列是否有就绪的事件,如果没有,那么会定义一个等待队列元素(自己起名ep_que,后都是用改名表示),将当前进程关联到ep_que,并且在注册一个回调函数default_wake_function,最后将ep_que存放到eventpoll结构的等待队列wq中。当前进程进入阻塞,让出cpu,切换到其他进程(实际情景,这块几乎不可能让出cpu,会持续的工作,因为实际线上环境数据会源源不断的传递过来的)。

 2.4 数据到来

   当有数据到来时,首先网卡会通过DMA方式将数据存储至ringbuff中,内核线程ksoftirq会将调用软中断处理函数将数据从ringbuff中取下来,根据内核中对应协议进行一些列处理,并且最终将数据存储到对应的socket的接收队列,之后中断处理函数sock_def_readable通过从socket的等待队列找到epoll_ctl调用时存储的关联epitem的元素,找到元素内之前注册的回到函数进行调用(epoll_poll_callback),该函数内存通过base指针找到指向的epitem元素,以及epoll对象上等待而被阻塞的进程号,并且会首先将找到的epitem元素添加到eventpoll结构中的就绪描述符队列中 ,接着判断eventpoll等待队列中是否有等待元素,如果有,找到等待元素的回调函数,通过获得的进程号将epoll_wait进程推入到运行队列,等待内核重新调度。并把eventpoll结构中就绪队列rdlist的时间返回给用户进程进行处理。

   

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值