Em "Programação Avançada no Ambiente UNIX" , W. Richard Stevens diz que é uma otimização de desempenho:
By specifying the highest descriptor we're interested in, the kernel can avoid going through hundred of unused bits in the three descriptor sets, looking for bits that are turned on.
(1ª edição, página 399)
Se você estiver fazendo qualquer tipo de programação de sistemas UNIX, o livro APUE é altamente recomendado.
ATUALIZAÇÃO
Um fd_set
geralmente é capaz de rastrear até 1024 descritores de arquivos.
A maneira mais eficiente de rastrear quais fds
estão definidas como 0
e quais estão definidas como 1
seria um bitset, então cada fd_set
consistiria em 1024 bits.
Em um sistema de 32 bits, um longo int (ou "word") é de 32 bits, então isso significa que cada fd_set
é |
1024/32 = 32 palavras.
Se nfds
é algo pequeno, como 8 ou 16, o que seria em muitas aplicações, ele só precisa olhar dentro da primeira palavra, o que deve ser claramente mais rápido do que procurar dentro de todas as 32.
(Veja FD_SETSIZE
e __NFDBITS
de /usr/include/sys/select.h
para os valores em sua plataforma.)
ATUALIZAÇÃO 2
Por que a assinatura da função não é
int select(fd_set *readfds, int nreadfds,
fd_set *writefds, int nwritefds,
fd_set *exceptfds, int nexceptfds,
struct timeval *timeout);
Meu palpite é que o código tenta manter todos os argumentos registrados , para que a CPU possa trabalhar neles mais rápido, e se tivesse que rastrear 2 variáveis extras, a CPU pode não ter registros suficientes.
Em outras palavras, select
está expondo um detalhe de implementação para que possa ser mais rápido.
- O BSD 4.4 Lite seleciona o código-fonte (selecione e selscan funções)
- Linux 2.6.37 selecione o código-fonte (funções do_select e max_select_fd)