Увеличение предела 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() является простой заменой 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 для сервера, который я разрабатывал