Запрос на выбор системного вызова - PullRequest
6 голосов
/ 13 марта 2009

select () определяется как:

int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *timeout);

nfds представляет самый высокий дескриптор файла во всех заданных наборах плюс один. Я хотел бы знать, почему эти данные требуются для select (), когда доступна информация fd_set.

Если FD в наборе, скажем, 4, 8, 9, значение nfds будет 10. Было бы select () moniter fds 9,8,7,6,5,4?

Ответы [ 3 ]

8 голосов
/ 13 марта 2009

Загвоздка в том, что fd_set на самом деле не «набор» в вашем мышлении. Закулисная деталь заключается в том, что реализация fd_set - это просто целое число, которое используется как битовое поле. Другими словами, выполнение

fd_set foo;
FD_CLEAR(&foo);
FD_SET(&foo, 3);

Устанавливает foo в десятичное значение 8 - устанавливает четвертый младший бит в 1 (помните, что 0 является допустимым дескриптором).

FD_SET(&foo, 3);

эквивалентно

foo |= (1 << 3);

Таким образом, чтобы выбор работал правильно, он должен знать, какие биты fd_set являются битами, которые вас интересуют. В противном случае не было бы никакого способа сообщить нулевому биту, который находится «в» наборе, но установлен в false из нулевого бита, который «не в» наборе.

В вашем примере набор fd_set с 4, 8 и 9 установленным и n = 10 интерпретируется как "Набор с 10 записями (fds 0-9). Записи 4, 8 и 9 являются истинными (следите за ними) . Записи 1, 2, 3, 5, 6, 7 являются ложными (не отслеживайте их). Любое значение fd, превышающее 9, просто не находится в установленном периоде. "

0 голосов
/ 13 марта 2009

Вероятно, это оптимизация, так что select не нужно проходить через все fd_set, чтобы выяснить, какие дескрипторы фактически используются. Без этого параметра select всегда нужно было бы просматривать весь набор, чтобы определить, какие дескрипторы фактически используются в вызове, а с параметром некоторые из этих действий можно опустить.

0 голосов
/ 13 марта 2009

Выберите контролирует те FD, которые вы включили с помощью макроса FD_SET. Если вы не включили ни один FD для мониторинга, select () не контролирует никаких.

«nfds» определенно избыточен, но он является частью интерфейса select (), поэтому вам нужно его использовать:)

В любом случае, если у вас есть {4, 8, 9} в наборе, вы устанавливаете nfds на 10 (как вы упоминали), и select () будет контролировать только три FD 4, 8 и 9.

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