epoll的实现原理

        为什么要了解epoll的实现原理?由于在某些环境中项目需要用户态实现tcp协议栈,而内核的epoll对内核的tcp套接字做了管理,而用户态的tcp协议栈得到的fd是设备文件系统的fd并不是内核的tcp套接字,因此不包含对tcp四元组的管理。因此需要了解epoll实现原理来自己实现一个用户态的epoll,来对tcp的四元组做管理。

epoll的数据结构

        epoll的接口有三个,epoll_createepoll_ctlepoll_wait

        epoll_create创建一个IO多路复用的管理对象epoll_ctlepoll_create创建的管理对象的操作,增加、删除和修改需要IO事件检测fd。epoll_wait对epoll_create创建的管理对象中的fd进行IO事件检测,并把触发事件的fd对应的数据copy出来。

        epoll_create成功创建一个管理对象会返回一个ep_fd索引,epoll_ctlepoll_wait只需要对ep_fd操作就是对创建的管理对象的操作了。

        管理对象中,包含了一个存储所有向管理对象增加IO事件检测fd集合和一个就绪集合fd集合是个红黑树,而就绪集合是个就绪链表队列hash表btree/b+tree相对于红黑树,hash表一开始创建的空间比较多,但是数据量大的时候查询速度快。btree/b+tree主要是多叉树降低层高,适用于硬盘存储。

        fd集合就绪集合的节点是同一个节点,加入就绪队列,其实就是把就绪队列最后一个节点的后继指针指向加入的节点,把加入节点的前置指针指向就绪队列最后一个节点。

协议栈如何与epoll模块通信

        IO事件检测主要有EPOLLIN事件的触发与EPOLLOUT事件的触发。

        EPOLLIN事件触发有三种,一种是listen后然后完成三次握手后建立连接加入到全连接队列的时候触发,一种是读缓冲区可读的时候触发,一种是接收到对端发送的FIN标识的包的时候触发。EPOLLOUT事件的触发是写缓冲区可写的时候触发。

        协议栈通过把触发事件的fd触发的事件作为参数调用回调函数查找对应的节点,然后把节点加入到就绪队列。用户通过epoll_wait读取就绪队列的节点内容。

        以上的事件触发条件都是LT(水平触发)的时候的表现。ET(边缘触发)的时候,EPOLLIN事件触发有一点不一样,把读缓冲区可读的时候触发改为有数据加入读缓冲区的时候触发。EPOLLOUT时间的触发也不一样,把写缓冲区可写的时候触发改为写缓冲区从不可写变为可写的时候触发。

        另外注意的是,在et模式下,同时注册了EPOLLINEPOLLOUT事件,只要EPOLLIN(或者EPOLLOUT)触发了,那么如果写缓冲区可写(或者读缓冲区可读),那么触发的事件也有EPOLLOUT(或者EPOLLIN)。

epoll如何加锁

        epoll_create创建管理对象不用加锁

        epoll_ctl对红黑树加互斥锁

        epoll_wait加入就绪队列的时候加自旋锁,因为锁住的操作就是push到就绪队列或者从就绪队列pop出来,这个操作的指令并不复杂,时间耗费上比线程切换上下文耗费的时间更加小。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值