Почему FD_SET / FD_ZERO для select () внутри цикла? - PullRequest
22 голосов
/ 03 октября 2011

Я использую функцию выбора для связи между моими сокетами.У меня есть цикл while, и я делаю -

    while(!done) {

    FD_ZERO(&read_flags);
    FD_ZERO(&write_flags);
    FD_SET(comm_fd1, &read_flags);
    FD_SET(comm_fd2, &read_flags);
    FD_SET(STDIN_FILENO, &read_flags);
    FD_SET(comm_fd1, &write_flags);
    FD_SET(comm_fd2, &write_flags);
    FD_SET(STDIN_FILENO, &write_flags);

    //call select
    sel = select(comm_fd1+comm_fd2+1, &read_flags, &write_flags, (fd_set*)0, &waitd);

и то же самое с разными переменными на стороне клиента.Я получил эту базовую технику из учебного онлайн и просто пошел с ней.Затем меня поразило - почему я очищаю набор и добавляю файловые дескрипторы при каждом цикле?Если они уже добавлены, зачем их очищать и добавлять снова?Поэтому я попытался сделать это только один раз, и код больше не работает.Может кто-нибудь объяснить, почему?Это только потому, что select изменяет содержимое набора?Любая помощь и / или понимание приветствуется.

Ответы [ 2 ]

25 голосов
/ 03 октября 2011

Когда возвращается select, он обновил наборы, чтобы показать, какие файловые дескрипторы готовы для чтения / записи / исключения.Все остальные флаги были сброшены.

Важно, чтобы вы снова включили дескрипторы файлов, которые были очищены до начала другого выбора, в противном случае вы больше не будете ждать этих дескрипторов файлов.

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

5 голосов
/ 03 октября 2011

Это просто потому, что select изменяет содержимое набора?

Да, после возврата select в наборах остаются только готовые дескрипторы.

...