关于处理超过 1024 个套接字描述符
Posted
技术标签:
【中文标题】关于处理超过 1024 个套接字描述符【英文标题】:Regarding handling more than 1024 socket descriptors 【发布时间】:2012-06-18 04:22:47 【问题描述】:我在 Linux 上使用 C 语言编写了一个聊天服务器。我已经测试过了,它在性能方面工作得很好。唯一滞后的是我正在使用 select 系统调用来处理套接字描述符。由于 select 的限制为 1024,所以我的聊天服务器最多只能同时处理 1024 个用户。
我知道我可以使用的另一个选项是 poll,但与 select 相比,我不太确定它及其性能。
请建议我解决这种情况的最有效方法。
【问题讨论】:
Handling more than 1024 file descriptors, in C on Linux的可能重复 肯定使用 epoll 而不是 select Christian.K 上面提供的链接明确地为这个问题提供了解决方案。 在我的程序中我可以重新定义 __FD_SETSIZE 因为 fdset 从系统文件中获取它 【参考方案1】:poll()
可以用作select()
的几乎直接替代品,并且允许您超过 1024 个文件描述符(您可以使传递给poll()
的数组尽可能大)。
它将具有与select()
相似的性能特征,因为两者都需要内核和用户空间应用程序来扫描整个阵列 - 但如果select()
对您来说工作正常,那么poll()
也应该如此。 (实际上poll()
的性能略有提升——.events
字段,为每个文件描述符指定您感兴趣的事件,不会被poll()
更改,因此您不必在之前重建数组每次调用都像你对传递给select()
的文件描述符集所做的那样。
如果以后发现自己因为扫描 poll 文件描述符数组而导致性能问题,可以考虑切换到epoll
接口,该接口更复杂,但对于非常多的文件描述符也可以更好地扩展。
【讨论】:
【参考方案2】:Linux 对 select() 没有 1024 个限制。但是:
-
select() 性能很差
FreeBSD 可以:)
你可以使用 poll()。但是当活动连接数增加时,它的性能会受到影响。
在 Linux 上使用 epoll() 更好,但我建议使用 libevent
libevent 是实现重负载服务器的快速、干净和可移植的方式,对于 linux,它具有 epoll。
【讨论】:
【参考方案3】:您的问题被称为C10K problem(如何处理超过 1 万个同时连接)。你会在网上找到很多资源,例如this one.
您应该将select
视为过时的系统调用。即使只有几十个文件描述符,你至少应该更喜欢poll
请注意,Qt 和 Gtk 为您提供了事件循环机制,通常使用 poll
(并且 QtCore 或 Glib 可以在 图形 界面之外使用)。还有libev 和libevent。我建议使用其中之一。
【讨论】:
以上是关于关于处理超过 1024 个套接字描述符的主要内容,如果未能解决你的问题,请参考以下文章