Подтвердить что ты не робот

Увеличение лимита FD_SETSIZE и выбор

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

4b9b3361

Ответ 1

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

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

Ответ 2

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

Ответ 3

Было бы лучше (и легко) заменить опрос. Как правило, 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
}

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

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

Ответ 4

Чтобы использовать fd_set больше, чем FD_SETSIZE, можно определить расширенный, например:

#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.

Ответ 5

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

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

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