关于Epoll的epoll_event.data的使用

        这两天公司开了新项目,后端使用Golang写的,于是想着用Golang来写个小玩意练练手,于是把目标对准了Golang中的net/http包,写个简单的收发文件的应用,在查找net/http的API的时候意外发现它底层使用的是epoll实现,这才突然想起来之前做C++网络编程的时候看到过epoll的部分,但是当时没有去详细了解,也就粗略知道个轮询的关键字就没再深究,这次正好有时间,就正好借着这个机会补一下这块的缺漏。

        另外吐槽一下找这种奇葩的资料真难找,找了很多资料才搞明白。这篇博客也是希望帮助更多想深入了解epoll_event.data用法的哥们。

1、Epoll基础知识

        Epoll主要用于实现多路复用技术,关于多路复用的实现方式总共有三种:select、poll、epoll,其中poll是对select的优化,但是治标不治本,所以这里仅对比一下select和epoll。

        

        Epoll向来以性能著称,但是它和select之间的性能到底差在哪里,这是必须知晓的,要谈性能差距,肯定要从他们的实现方式开始聊了。

        select的实现方式是给定一个文件描述符的队列,持续监听这个队列,当内核监听到有文件描述符的状态发生变化时,通知select进行处理,当select收到通知后,它只知道队列中有描述符就绪了,但是是哪个描述符并不清楚,所以需要遍历这个队列,查找哪些文件描述符准备就绪,然后进行接下来的操作,于是时间复杂度来到了O(N),同时它有一个比较大的弊端就是一个select只能监听1024个文件描述符,虽然可以通过改写头文件重新编译内核或者进行多线程select来缓解这个问题,但是终归是治标不治本,于是就由epoll来解决这两个比较大的问题了。

        epoll的实现方式是给定一个epoll事件池与一个epoll_event数组(我称之为事件数组),这个事件池不限制最多能放入的事件个数,这就解决了select最多只能监听1024个文件描述符的问题,指定事件池后,同样由内核来监听每个事件的文件描述符与其指定的事件(每个事件是一个结构体,其中包含文件描述符和要等待的事件,看后面就能明白),当监听到文件描述符到达指定的状态时,由内核主动将就绪的事件拷贝到epoll_event数组中并返回就绪的描述符数量(这个拷贝由内核完成,效率很高),于是epoll能够直接获取到是哪些事件就绪,可以直接对epoll_event进行遍历,而不需要将事件池中的所有事件遍历,则直接将时间复杂度优化到了O(1),同时能够对每个事件附带一个data数据,在得到就绪的文件描述符时就能够一并得到它的状态。

        介绍完了实现方式,他们之间的性能差距也就一目了然了,对于epoll的系统实现,可以看这篇文章,它对epoll的底层解释的比较详细。

2、Epo

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值