Я хочу увеличить значение макроса FD_SETSIZE для моей системы. Есть ли способ увеличить FD_SETSIZE, поэтому select не будет терпеть неудачу.
Увеличение лимита FD_SETSIZE и выбор
Ответ 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 для сервера, который я разрабатывал