Увеличение предела FD SETSIZE и выбор

Я хочу увеличить значение макроса FD_SETSIZE для моей системы. Есть ли способ увеличить FD_SETSIZE, поэтому select не подведет

5 ответов


в соответствии со стандартами, нет никакого способа увеличить FD_SETSIZE. Некоторые программы и библиотеки (libevent приходит на ум) пытаются обойти это, выделив дополнительное пространство для fd_set объект и передача значений больше, чем FD_SETSIZE до FD_* макросы, но это очень плохая идея, так как надежные реализации могут выполнять проверку границ аргумента и прерывать его, если он находится вне диапазона.

у меня есть альтернативное решение, которое всегда должно работать (хотя это не обязательно по стандартам). Вместо одного fd_set объект, выделите массив из них достаточно большой, чтобы вместить max fd, который вам понадобится, а затем используйте FD_SET(fd%FD_SETSIZE, &fds_array[fd/FD_SETSIZE]) etc. чтобы получить доступ к набору.


Я также предлагаю использовать poll Если это возможно. И существует несколько библиотек обработки "событий", таких как libevent или libev (или способности события Глеб от GTK, или модулями QtCore и т. д.), которые должны помочь вам. Есть также такие вещи, как epoll. И ваша проблема связана с C10k


было бы лучше (и легко) заменить на опрос. Как правило, poll() является простой заменой select () и не ограничивается 1024 FD_SETSIZE...

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
}

вам нужно включить опрос.h для структуры pollfd.

Если вам нужно писать, а также читать, установите флаг событий как POLLIN / POLLOUT.


можно увеличить fd_setsize overiding __FD_SETSIZE (определяется в sys/types.h) перед включением sys/select.h.

продолжая так, мы можем установить FD_SETSIZE до 2048 :

#include <sys/types.h>
#undef __FD_SETSIZE
#define __FD_SETSIZE 2048
#include <sys/select.h>
#include <stdio.h>

int main()
{
    printf("FD_SETSIZE:%d sizeof(fd_set):%d\n",FD_SETSIZE,sizeof(fd_set));
    return 0;
}

выведет :

FD_SETSIZE: 2048 sizeof (fd_set):128

однако, если FD_SETSIZE следует измененному значению, sizeof (fd_set) должен быть 256 (2048/8), а не 128 (1024/8). Это потому, что в том числе sys/types.h определись уже fd_set с 1024.


для того, чтобы использовать больше 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 filedescriptors, необходимо увеличить лимит, используя, например,ulimit -n 2048.

на самом деле есть IS способ увеличить FD_SETSIZE в windows. его определяют в winsock.h и для самих microsoft вы можете увеличить его, просто определив его перед включением winsock.h

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

Я делаю это все время, и у меня не было проблем наибольшее значение, которое я использовал, было около 5000 для сервера, который я разрабатывал