增加FD_SETSIZE的限制并选择

时间:2011-11-02 06:02:51

标签: c linux file-descriptor

我想为我的系统增加FD_SETSIZE宏值。 有没有办法增加FD_SETSIZE所以选择不会失败

5 个答案:

答案 0 :(得分:13)

我还建议尽可能使用poll。并且存在几个"事件"处理诸如libeventlibev之类的库(或来自GTK的Glib的事件能力,或QtCore等)应该对您有所帮助。还有epoll之类的东西。而且您的问题与C10k

有关

答案 1 :(得分:12)

根据标准,无法增加FD_SETSIZE。一些程序和库(想到了libevent)尝试通过为fd_set对象分配额外空间并将大于FD_SETSIZE的值传递给FD_*宏来解决此问题,但这是一个非常糟糕的主意,因为健壮的实现可以对参数执行边界检查,如果超出范围则中止。

我有一个应该始终有效的替代解决方案(即使标准不要求它)。而不是单个fd_set对象,分配一个足够大的数组来保存您需要的最大fd,然后使用FD_SET(fd%FD_SETSIZE, &fds_array[fd/FD_SETSIZE])等来访问该集合。

答案 2 :(得分:8)

用民意调查取代会更好(也更容易)。通常poll()是select()的简单替代品,并且不受UP_SETSIZE的1024的限制...

fd_set fd_read;
int id = 42;
FD_ZERO(fd_read);
FD_SET(id, &fd_read);
struct timeval tv;
tv.tv_sec = 5;
tv.tv_usec = 0;
if (select(id + 1, &fd_read, NULL, NULL, &tv) != 1) {
   // Error.
}

变为:

struct pollfd pfd_read;
int id = 42;
int timeout = 5000;
pfd_read.fd = id;
pfd_read.events = POLLIN;
if (poll(&pfd_read, 1, timeout) != 1) {
   // Error
}

您需要为pollfd结构包含poll.h。

如果你需要写和读,那么将事件标志设置为POLLIN | POLLOUT。

答案 3 :(得分:6)

为了使用大于FD_SETSIZE的fd_set,可以像这样定义扩展名:

#include <sys/select.h>
#include <stdio.h>

#define EXT_FD_SETSIZE 2048
typedef struct
{
    long __fds_bits[EXT_FD_SETSIZE / 8 / sizeof(long)];
} ext_fd_set;

int main()
{
    ext_fd_set fd;
    int s;
    printf("FD_SETSIZE:%d sizeof(fd):%ld\n", EXT_FD_SETSIZE, sizeof(fd));
    FD_ZERO(&fd);
    while ( ((s=dup(0)) != -1) && (s < EXT_FD_SETSIZE) )
    {
        FD_SET(s, &fd);
    }
    printf("select:%d\n", select(EXT_FD_SETSIZE,(fd_set*)&fd, NULL, NULL, NULL));
    return 0;
}

打印:

  

FD_SETSIZE:2048 sizeof(fd):256

     

选择:2045

<小时/> 为了打开超过1024个文件描述符,需要使用例如ulimit -n 2048来增加限制。

答案 4 :(得分:2)

实际上 IS 是一种在Windows上增加FD_SETSIZE的方法。它在winsock.h中定义,并且每个微软本身你可以通过在包含winsock.h之前简单地定义它来增加它。

http://support.microsoft.com/kb/111855

我一直这样做并没有遇到任何问题我使用的最大值是5000左右我正在开发的服务器