c++ - 使用带有大量文件描述符的 select() 的外部代码

标签 c++ linux sockets select epoll

我有一个用 C++ 编写的服务器程序,它在 Linux 上运行并使用 TCP 实现基于推送的消息服务。由于推送方法,可能有很多同时连接(我计划大约 100 万)必须保持打开更长时间。大多数情况下,这些连接处于空闲状态,偶尔会发出心跳,并且传输通常会同时在许多连接上突发。

为了让事情正常进行,我使用 epoll 来多路复用大量的套接字,并且通过修改 RLIMIT_NOFILE,它实际上对大量的套接字工作得很好套接字。

我的问题是我还在同一个程序中使用其他类型的连接,最著名的是 FastCGI(使用 FastCGI SDK 中的 libfcgi)来接受 HTTP 请求,它使用 select()它们的内部文件描述符。当这些文件描述符变得大于 1024 (FD_SETSIZE) 时,这会导致问题,如果程序的 epoll 部分用完下面的大部分 fd 数字,这必然会发生1024.

我想知道处理这个问题的最佳方法是什么。

我是否只需要修改所有使用 select() 的外部代码并改为使用 poll()

有没有办法强制我的基于 epoll 的代码(特别是 accept() 调用)只使用 1024 以上的文件描述符,这样下面的那些为基于select() 的代码保留?

我知道可以通过某种方式增加 FD_SETSIZE 的值,但我认为由于 select() 的工作方式,这会严重损害性能,在我看来,它是一种 hack 而不是真正的解决方案。

最佳答案

我建议将这些东西移动到它们自己的进程中,以便它们获得自己的文件描述符。我建议你有一个协议(protocol),可以在单个 TCP 连接上多路复用大量 TCP 连接。您的服务器将与多路复用器而不是单个客户端通信。多路复用器可以在同一台机器或不同机器上运行,它可以处理数万个客户端连接,并且只会与服务器建立一个连接。

这样做的一大优势是您的服务器机器不必处理大量的 TCP 连接状态。它不必处理 Internet 垃圾,例如丢包、重传、重复包、流氓 SYN、慢速链接等。它不必为每个客户端都设置发送缓冲区,而只需与可以为客户端进行缓冲的快速、干净的多路复用器通信。

如果工作量太大或由于某种原因无法实现,您可以使用 dup2 将文件描述符重新编号为更高编号的描述符。不过,我强烈建议使用多路复用器——您尝试处理的连接数量太大,无法从单个进程处理。

关于c++ - 使用带有大量文件描述符的 select() 的外部代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42962495/

相关文章:

c++ - 操作系统回调如何工作

c++ - 在C++中将json值转换为int

ruby - Ruby 中的 Kernel#select 有什么意义?

C# - 套接字未接收所有字节

可以通过本地主机连接到我的程序,但无法使用网络上的其他计算机进行连接

c++ - 将由类组成的 vector 传递给函数 (C++)

可以*仅*放在堆栈上的 C++ 类?

Linux shell脚本编程基础 : making a command-line tool that executes a command to execute several

linux - 将行移至新文件 sed、awk 或其他文件

c++ - Windows 中使用 IP Helper 的事件 UDP 连接的远程地址