![]() |
1
184
对于非常少量的套接字(当然,取决于您的硬件,但我们讨论的是10个或更少的数量),选择可以在内存使用和运行时速度上击败epoll。当然,对于如此少的套接字,这两种机制都非常快,以至于在大多数情况下您并不真正关心这种差异。
不过,有一个解释。select和epoll都是线性缩放。但是,一个很大的区别是面向用户空间的API具有基于不同事物的复杂性。A的成本
epoll的成本更接近于实际包含事件的文件描述符的数量。如果您监视的是200个文件描述符,但其中只有100个上面有事件,那么(非常粗略地)您只需要为这100个活动的文件描述符付费。这就是epoll比select更具优势的地方。如果你有上千个客户机大部分都是闲置的,那么当你使用Select时,你仍然要为所有的一千个客户支付费用。然而,使用epoll,就好像你只有少数人——你只为在任何给定时间活跃的人付费。
所有这些都意味着epoll将减少大多数工作负载的CPU使用量。就内存使用而言,这有点麻烦。
还有epoll的另一个好处,也许您已经知道了,它不局限于fd setize文件描述符。您可以使用它来监视尽可能多的文件描述符。如果您只有一个文件描述符,但其值大于fd_setsize,epoll也可以使用它,但是
随机地,我最近还发现了
另一方面,
在实践中,我看到的唯一一个地方是与stdio交互时。用户可以将stdin或stdout从/重定向到普通文件。以前的stdin和stdout应该是一个管道,由epoll支持,但很好,然后它变成一个普通文件,epoll会很大声地失败,从而破坏应用程序。 |
|
2
4
在我公司的测试中,出现了epoll()的一个问题,因此与select相比,它的成本是单一的。 当试图在超时情况下从网络中读取数据时,创建epoll_fd(而不是fd_集),并将fd添加到epoll_fd,比创建fd_集(这是一个简单的malloc)要昂贵得多。 根据前面的答案,随着过程中FDS的数量越来越大,select()的成本也越来越高,但是在我们的测试中,即使fd值在10000中,select仍然是赢家。在这种情况下,一个线程只有一个fd在等待,并且只是试图克服这样一个事实:当使用阻塞线程模型时,网络读取和网络写入不会超时。当然,与非阻塞反应器系统相比,阻塞线程模型的性能较低,但有时需要与特定的遗留代码库集成。 这种用例在高性能应用中很少见,因为一个反应堆模型不需要每次都创建一个新的epoll-fd。对于epoll-fd是长寿命的模型——这显然是任何高性能服务器设计的首选——epoll在各个方面都是明显的赢家。 |