Подтвердить что ты не робот

Почему FD_SET/FD_ZERO для select() внутри цикла?

Я использую функцию select для связи между моими сокетами. У меня есть цикл 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 изменяет содержимое набора? Любая помощь и/или понимание понятны.

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

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