【问题标题】:Regarding handling more than 1024 socket descriptors关于处理超过 1024 个套接字描述符
【发布时间】:2012-06-18 04:22:47
【问题描述】:

我在 Linux 上使用 C 语言编写了一个聊天服务器。我已经测试过了,它在性能方面工作得很好。唯一滞后的是我正在使用 select 系统调用来处理套接字描述符。由于 select 的限制为 1024,所以我的聊天服务器最多只能同时处理 1024 个用户。

我知道我可以使用的另一个选项是 poll,但与 select 相比,我不太确定它及其性能。

请建议我解决这种情况的最有效方法。

【问题讨论】:

  • 肯定使用 epoll 而不是 select
  • Christian.K 上面提供的链接明确地为这个问题提供了解决方案。
  • 在我的程序中我可以重新定义 __FD_SETSIZE 因为 fdset 从系统文件中获取它

标签: c++ c linux linux-kernel socketserver


【解决方案1】:

poll() 可以用作select() 的几乎直接替代品,并且允许您超过 1024 个文件描述符(您可以使传递给poll() 的数组尽可能大)。

它将具有与select() 相似的性能特征,因为两者都需要内核和用户空间应用程序来扫描整个阵列 - 但如果select() 对您来说工作正常,那么poll() 也应该如此。 (实际上poll() 的性能略有提升——.events 字段,为每个文件描述符指定您感兴趣的事件,不会被poll() 更改,因此您不必在之前重建数组每次调用都像你对传递给select()的文件描述符集所做的那样。

如果以后发现自己因为扫描 poll 文件描述符数组而导致性能问题,可以考虑切换到epoll 接口,该接口更复杂,但对于非常多的文件描述符也可以更好地扩展。

【讨论】:

    【解决方案2】:

    Linux 对 select() 没有 1024 个限制。但是:

    1. select() 性能很差
    2. FreeBSD 可以:)

    你可以使用 poll()。但是当活动连接数增加时,它的性能会受到影响。

    在 Linux 上使用 epoll() 更好,但我建议使用 libevent

    libevent 是实现重负载服务器的快速、干净和可移植的方式,对于 linux,它具有 epoll。

    【讨论】:

      【解决方案3】:

      您的问题被称为C10K problem(如何处理超过 1 万个同时连接)。你会在网上找到很多资源,例如this one.

      您应该将select 视为过时的系统调用。即使只有几十个文件描述符,你至少应该更喜欢poll

      请注意,Qt 和 Gtk 为您提供了事件循环机制,通常使用 poll(并且 QtCore 或 Glib 可以在 图形 界面之外使用)。还有libevlibevent。我建议使用其中之一。

      【讨论】:

        猜你喜欢
        • 2010-10-25
        • 1970-01-01
        • 2012-11-12
        • 1970-01-01
        • 2010-09-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-12-03
        相关资源
        最近更新 更多