Чтение, запись и обработка исключений fd_set с помощью select () в C - PullRequest
0 голосов
/ 08 ноября 2019

Если я использую select () для отслеживания трех наборов файловых дескрипторов:

if (select(fdmax+1, &read_fds, &write_fds, &except_fds, NULL) == -1) {
    perror("select()");
    exit(1);
} else {
    ...
}
  1. Может ли конкретный файловый дескриптор быть готовым для чтения, записи и обработки исключений одновременно?

  2. Популярная сетевая страница Биджа показывает пример select (), в котором он проверяет членов read fd_set, используя цикл for. Поскольку цикл увеличивается на одну каждую итерацию, он обязательно протестирует некоторые целые числа, которые, как оказалось, не являются существующими файловыми дескрипторами:

for(i = 0; i <= fdmax; i++) {
    if (FD_ISSET(i, &read_fds)) { // we got one!!
    {
        ...
    }
}

Я полагаю, что он делает это радисохраняя простой пример кодаМожет / нужно только протестировать существующие файловые дескрипторы?

Ответы [ 2 ]

2 голосов
/ 08 ноября 2019

Немного расширив примеры и @ user207421 комментарий:

1 Может ли определенный дескриптор файла быть готовым для чтения, записи и обработки исключений одновременно?

ХорошоПримером будет сокет, который (почти) всегда будет готов к записи и будет готов к чтению, когда будут доступны данные. Обычно встречаются исключения - они используются для exceptional ситуаций. Например, наличие внеполосного сообщения в соединениях TCP, но большинство приложений не используют эти функции.

Обратите внимание, что в readfds будут отображаться «нормальные» ошибки (например, отключение сокета).

См. Также: * nix select и семантика excalfds / errorfds ,

На популярной сетевой странице Beej показан пример select (), в котором он проверяет участников. чтения fd_set с помощью цикла for. Поскольку цикл увеличивается на одну каждую итерацию, он обязательно будет проверять некоторые целые числа, которые не являются существующими файловыми дескрипторами:

Я считаю, что в этом случае это делается для упрощения примеров кода,и является разумной реализацией для большинства легких реализаций. Это работает хорошо, если число подключений без прослушивания очень мало.

Стоит отметить, что 'fd_set' реализован в Linux с набором битов, но в Windows (winsock) как массив значений fd,Полное сканирование всех FD будет O (n) в Linux и O (n * n) в Windows. Это может сильно повлиять на производительность большого приложения N для Windows.

В крупномасштабных приложениях, где сервер будет прослушивать сотни (или более) открытых соединений, каждое из которых требует различных действий, потенциально с несколькими состояниями,обычной практикой будет наличие списка активных соединений и использование обратного вызова для вызова функции. Обычно это реализуется с помощью 'Eventloop'. Примеры включают X11, серверы rpc и т. Д.

См. Также: https://en.wikipedia.org/wiki/Event_loop

0 голосов
/ 09 ноября 2019

Ваш вопрос: , почему вы используете select (), если у вас есть только один сокет.

, когда используется select, и вы не хотите, чтобы он блокировал другую обработку. Затем воспользуйтесь параметром timeout.

Таким образом, даже если открыт только один дескриптор файла, программа не будет блокироваться вечно из-за того, что один дескриптор файла не получает никаких данных, как это было бы при использовании read()или аналогичная функция.

IE, это очень хороший метод, например, при прослушивании последовательного порта, который имеет данные только при возникновении какого-либо внешнего события.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...