В статье «Расширенное программирование в среде 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
Относительно того, почему подпись функции не
int select(fd_set *readfds, int nreadfds,
fd_set *writefds, int nwritefds,
fd_set *exceptfds, int nexceptfds,
struct timeval *timeout);
Я думаю, это потому, что код пытается сохранить все аргументы в регистрах , чтобы ЦПУ мог работать с ними быстрее, и если бы ему пришлось отслеживать дополнительные 2 переменные, ЦП может не иметь достаточно регистров.
Другими словами, selectраскрывает детали реализации, чтобы они могли быть быстрее.