От man select
int select(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout);
nfds - дескриптор файла с наибольшим номером в любом из трех наборов плюс 1.
Какова цель nfds
, когда у нас уже есть readfds
, writefds
и exceptfds
из которого могут быть определены файловые дескрипторы?
system-calls
file-descriptors
phunehehe
источник
источник
Ответы:
В статье «Расширенное программирование в среде UNIX» Ричард Стивенс говорит, что это оптимизация производительности:
(1-е издание, стр. 399)
Если вы занимаетесь программированием любых систем UNIX, настоятельно рекомендуется книга APUE.
ОБНОВИТЬ
fd_set
, Как правило , в состоянии отслеживать до 1024 дескрипторов файлов.Наиболее эффективный способ отследить, какие из
fds
них установлены,0
а какие установлены, - это набор битов1
, поэтому каждый из нихfd_set
будет состоять из 1024 битов.В 32-битной системе long int (или «слово») составляет 32 бита, так что каждый из них
fd_set
равен1024/32 = 32 слова.
Если
nfds
есть что-то маленькое, например, 8 или 16, которое было бы во многих приложениях, ему нужно только заглянуть внутрь 1-го слова, которое должно быть явно быстрее, чем заглянуть внутрь всех 32.(См
FD_SETSIZE
и__NFDBITS
с/usr/include/sys/select.h
для значений на вашей платформе.)ОБНОВЛЕНИЕ 2
Относительно того, почему подпись функции не
Я думаю, это потому, что код пытается сохранить все аргументы в регистрах , чтобы ЦПУ мог работать с ними быстрее, и если бы ему пришлось отслеживать дополнительные 2 переменные, ЦП может не иметь достаточно регистров.
Другими словами,
select
раскрывает детали реализации, чтобы они могли быть быстрее.источник
Я не знаю наверняка, так как я не один из разработчиков select (), но я бы сказал, что это оптимизация производительности. Вызывающая функция знает, сколько файловых дескрипторов она поместила в чтение, запись и, кроме FD, так почему же ядро должно это выяснить снова?
Помните, что в начале 80-х годов, когда появилась функция select (), у них не было мульти-гигагерцевых мультипроцессоров для работы. VAX с частотой 25 МГц был довольно быстрым. Кроме того, вы хотели, чтобы select () работал быстро, если мог: если какой-то ввод-вывод ожидал процесса, зачем заставлять процесс ждать?
источник
nreadfds
,nwritefds
аnexceptfds
не только одинnfds
.nfds
можно зайти в реестр для более быстрого доступа. Если бы ему нужно было отслеживать три числа вместе со всеми остальными аргументами, возможно, у ЦПУ не было бы достаточно регистров. Конечно, ядро могло бы создать свое собственноеnfds
на основе ваших гипотетических 3 переменных. Поэтому я предполагаю, что он раскрывает детали реализации для повышения эффективности.nfds
аргументы приносят очень мало пользы. В большинстве случаев процесс открыл очень мало процессов относительноFD_SETSIZE
. Типичный случай может иметь (4,4,2) из 1024; проверка ядра (4,4,4) - это большая победа (1024,1024,1024), но оптимизация до (4,4,2) была бы практически бесполезной.nfds
, либо быть ленивым и вызыватьselect(FD_SETSIZE, ...)
, что будет медленнее.)