Linux Epoll的使用方法

这个可能大家都知道,我稍微提一下:1、每次调用epoll的侦听函数epoll_wait时,它只会返回确实有事件发生的那些套接字,而不会返回所有注册的套接字,显然,这个会增强效率,特别是对于那些有大量的套接字,但套接字大多时候是处于休眠状态的场景;2、能够支持大量的套接字的同时监管:理论上讲,epoll能够支持整形所能表示的最大数值个套接字的监管(但实际上,这个上限往往由于机器体系结构、内存限制、网络限制等而不能达到);3、epoll所特有的ET模式,能够让你的CPU做“真正该做的事情”。

如何使用好ET模式?

ET模式最为人诟病的就是事件有时候不能被处理掉(往往由于用户会选择性地处理事件,比如,有可写事件到达,但我没有需要写的数据,于是就忽略该事件),导致该描述符后来对应的该事件不再被反应给用户。相当于,这个描述符已经淡出了用户的视野,成为了一个“死的”描述符,它将再不能被用户感知到。

实际上,可以有两种措施来避免这种情况的发生:

1、当“可读”事件到达时,就一直读这个描述符,知道该描述符不可读为止,这保证了此次事件通知被有效处理了,那么下次改描述符的该事件发生,系统还会通知用户。

2、现在说“可写”事件。用户可以为每个描述符维护一个写任务队列(具体数据结构如何实现,视情形而定),当用户想要发送一段数据时,需要先检查该描述符的写任务队列是否有任务。如果没有任务,则表明该描述符没有积压的写任务,这时候就可以直接异步发送,能发送多少就发送多少,发送不了的,新建一个写任务项,加入队列(这时队列里只有一项);如果任务队列有任务, 则表明之前的写任务没有全部完成,需要发送的数据将作为一个新的写任务添加到写任务队列中。当该描述符有可写事件到达时,就看写任务队列是否为空,如果为空,则不做任何事情;如果不为空,则尽量将写任务都完成(也即,尽量send数据)。

还有什么需要注意的?

1、如果涉及到大量连接的话,需要修改/etc/sysctl.conf文件中的几项,另外,单个套接字的接收缓冲区和发送缓冲区也需要设置(包括配置文件和程序中调用setsockopt函数)。再有就是如果单机连接数需要上20w以上的话,最好是拿64位机子做服务器,因为32位机子的系统内存只有1G,很难容下大量套接字缓冲区的。

2、还是老生常谈,尽量减少内存拷贝。

epoll到底有多厉害?

在笔者的实际应用中,单机并发连接数达到过18w(网络环境不怎么样,带宽只有100Mb/s),网上有的人已经测试过能达到50w级别的。当然,这个只是给大家一个直观的了解,具体能到多少连接数,以及数据吞吐率怎么样,那要视您的环境以及业务需求了。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wwsggs.html