C++ 处理FD_SETSIZE on select

C++ 处理FD_SETSIZE on select,c++,c,networking,network-programming,C++,C,Networking,Network Programming,我们有一个使用select()设计的web服务器,它直到上周才真正看到过很多负载,而且对于我们的500-1000 conn/s负载,它总是工作得很好。然而,我们最近开始看到更高的负载(和峰值),并在看到套接字句柄>FD_SETSIZE之后遇到了select()变得疯狂的问题。如果服务器的FD_集合中有任何>FD_SETSIZE的内容,那么在重复超时后,select将进入一个不可中断的循环,这将使服务器冻结。切换到poll(或epoll)的选项现在不存在,我们必须坚持选择。我现在修复它的方法是增加

我们有一个使用select()设计的web服务器,它直到上周才真正看到过很多负载,而且对于我们的500-1000 conn/s负载,它总是工作得很好。然而,我们最近开始看到更高的负载(和峰值),并在看到套接字句柄>FD_SETSIZE之后遇到了select()变得疯狂的问题。如果服务器的FD_集合中有任何>FD_SETSIZE的内容,那么在重复超时后,select将进入一个不可中断的循环,这将使服务器冻结。切换到poll(或epoll)的选项现在不存在,我们必须坚持选择。我现在修复它的方法是增加侦听队列,当我看到一个新连接返回accept()为>=FD_SETSIZE并返回到侦听套接字上的select()时,停止接受新连接。这是因为操作系统会回收文件句柄,并始终尝试提供最小的可用句柄。但缺点是,如果套接字句柄大于等于FD_SETSIZE,则在调用accept()时,我最终会向某些连接发送RST。目前这仍然是可以接受的,因为它可以保持服务器运行,并且连接断开率约为5%。有没有一种方法可以在不中断这些连接的情况下做到这一点。我不想把所有用过的手柄和东西都记下来,这会让事情变得太复杂。创建一个假套接字,检查它的句柄并在调用accept之前关闭它,这将相当准确地估计操作系统下一步将给我什么句柄

while(max_conn_to_accept--){
SOCKET a_s = accept(..);
if(a_s >= FD_SETSIZE){
    close(a_s);
    return;
}

只需升起
FD_SETSIZE
。在编译器命令行上指定
-DFD_SETSIZE=16384

我认为你的版本足够新,没有其他问题。如果头文件中出现错误,可能需要调整一两行

例如,如果您看到以下内容:

#undef __FD_SETSIZE
#define __FD_SETSIZE    1024
将其更改为:

#undef __FD_SETSIZE
#ifndef FD_SETSIZE
#define __FD_SETSIZE    1024
#else
#define __FD_SETSIZE    FD_SETSIZE
#endif
或者如果你看到:

#define FD_SETSIZE      1024
将其更改为:

#ifndef FD_SETSIZE
#define FD_SETSIZE      1024
#endif

但是,再一次,我认为您不需要更改任何内容。

只需提高
FD_SETSIZE
。在编译器命令行上指定
-DFD_SETSIZE=16384

我认为你的版本足够新,没有其他问题。如果头文件中出现错误,可能需要调整一两行

例如,如果您看到以下内容:

#undef __FD_SETSIZE
#define __FD_SETSIZE    1024
将其更改为:

#undef __FD_SETSIZE
#ifndef FD_SETSIZE
#define __FD_SETSIZE    1024
#else
#define __FD_SETSIZE    FD_SETSIZE
#endif
或者如果你看到:

#define FD_SETSIZE      1024
将其更改为:

#ifndef FD_SETSIZE
#define FD_SETSIZE      1024
#endif

但是,我想你不需要改变任何东西。

什么平台?您可能只需要提高
FD_SETSIZE
。在centos 5.7中,我搜索了提高FD_SETSIZE vut,但找不到任何这样做的平台。什么平台?您可能只需要提高
FD_SETSIZE
。在centos 5.7中,我搜索了提高FD_SETSIZE vut找不到任何方法。这看起来是一个不错的选择,我将尝试一下,谢谢David!不幸的是,这只适用于BSD或SYSV兼容的UNIX系统。特别是,如果不修改系统头文件,它在Linux上无法工作……幸运的是,修改头文件只需几秒钟。(虽然你确实需要根权限来做这件事。)是的,我最终修改了头文件,但在那之后工作得很好!这看起来是个不错的选择,我要试试,谢谢大卫!不幸的是,这只适用于BSD或SYSV兼容的UNIX系统。特别是,如果不修改系统头文件,它在Linux上无法工作……幸运的是,修改头文件只需几秒钟。(虽然你确实需要根权限来做这件事。)是的,我最终修改了头文件,但在那之后工作得很好!