En "Programación avanzada en el entorno UNIX" , W. Richard Stevens dice que es una optimización del rendimiento:
Al especificar el descriptor más alto en el que estamos interesados, el núcleo puede evitar pasar por cientos de bits no utilizados en los tres conjuntos de descriptores, buscando bits que estén activados.
(1a edición, página 399)
Si está haciendo algún tipo de programación de sistemas UNIX, el libro APUE es muy recomendable.
ACTUALIZAR
Un fd_set
generalmente puede rastrear hasta 1024 descriptores de archivo.
La forma más eficiente de rastrear cuáles fds
están configurados 0
y cuáles están configurados 1
sería un conjunto de bits, por lo que cada uno fd_set
consistiría en 1024 bits.
En un sistema de 32 bits, un int largo (o "palabra") es de 32 bits, lo que significa que cada uno fd_set
es
1024/32 = 32 palabras.
Si nfds
es algo pequeño, como 8 o 16, que sería en muchas aplicaciones, solo necesita mirar dentro de la primera palabra, que claramente debería ser más rápido que mirar dentro de los 32.
(Consulte FD_SETSIZE
y __NFDBITS
desde /usr/include/sys/select.h
los valores de su plataforma).
ACTUALIZACIÓN 2
En cuanto a por qué la firma de la función no es
int select(fd_set *readfds, int nreadfds,
fd_set *writefds, int nwritefds,
fd_set *exceptfds, int nexceptfds,
struct timeval *timeout);
Supongo que es porque el código intenta mantener todos los argumentos en los registros , por lo que la CPU puede trabajar en ellos más rápido, y si tuviera que rastrear 2 variables adicionales, la CPU podría no tener suficientes registros.
En otras palabras, select
está exponiendo un detalle de implementación para que pueda ser más rápido.