FD_SETSIZE против рассчитанного значения

В настройке сервера / клиента у меня есть сервер, соединяющийся с клиентами через несколько (на данный момент 4) различных сокетов. В данный момент я использую select с вычисленным значением set_size, но каков верхний предел, прежде чем вместо него стоит использовать FD_SETSIZE?

Ниже приведены некоторые примеры кода, чтобы проиллюстрировать это. Первый сборочный комплекс:

FD_ZERO(&set);
FD_SET(socket1, &set);
FD_SET(socket2, &set);
FD_SET(socket3, &set);
FD_SET(socket4, &set);

Вот как рассчитывается set_size:

set_size = MAX(socket1, socket2);
set_size = MAX(set_size, socket 3);
set_size = MAX(set_size, socket4);
set_size += 1;

И использование:

while ((cnt = select(set_size, &set, NULL, NULL, &t)) != -1 || errno == EINTR) {
    if (cnt > 0)
        // Do different stuff depending what socket is active
    else
        // Keep everything alive and add the sockets to the set again
}

Недавно мне пришлось добавить два новых сокета, и, возможно, мне придется добавить еще в будущем. Когда бы вы использовали FD_SETSIZE в отличие от рассчитанного set_size?

1 ответ

Решение

Я никогда не беспокоился об этом, потому что кажется, что это очень мало изменится по сравнению со снижением производительности за использование select() на первом месте.

Сказав это, я думаю, что всегда стоит рассчитывать правильное значение, потому что это не очень дорого, чтобы рассчитать: если вы сохраняете текущее set_size в локальной переменной, как вы предлагаете, это O(1) с очень низкой константой каждый раз, когда вы добавляете fd (а именно, сравнение и, возможно, обновление). Удаление fd также является O(1), за исключением того, что оно является последним в списке (в этом случае это O ( set_size ) но обычно лучше). С другой стороны, НЕ рассчитывая set_size означает, что ядро ​​должно пройти через все FD_SETSIZE записи каждый раз, когда вы звоните select, поскольку set_size вероятно, немного меньше, чем FD_SETSIZE, это платит, чтобы поставить меньшее значение. Даже если set_size близко к FD_SETSIZE, рассчитывая set_size так дешево, что, вероятно, почти всегда стоит.

Конечно, если вы беспокоитесь о производительности до такой степени, вы должны смотреть на poll() вместо select(), Еще лучше, вы должны смотреть на epoll а также kqueue за исключением того, что это не переносимо, так как эти функции доступны только в Linux и FreeBSD (включая MacOS) соответственно.

Другие вопросы по тегам