Qual é o propósito do primeiro argumento para selecionar a chamada do sistema?

24

De man select

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

nfds is the highest-numbered file descriptor in any of the three sets, plus 1.

Qual é o propósito de nfds , quando já temos readfds , writefds e exceptfds , a partir dos quais os descritores de arquivo podem ser determinados?

    
por phunehehe 21.02.2011 / 05:57

2 respostas

24

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.

por 21.02.2011 / 10:32
6

Não sei ao certo, já que não sou um dos designers do select (), mas diria que é uma otimização de desempenho. A função de chamada sabe quantos descritores de arquivo ela coloca na leitura, gravação e exceto FDs, então por que o kernel deveria descobrir isso de novo?

Lembre-se que no início dos anos 80, quando select () foi introduzido, eles não tinham multi-gigaghertz, multiprocessadores para trabalhar. Um VAX de 25 megahertz era consideravelmente doggone rápido. Além disso, você queria que select () trabalhasse rápido se pudesse: se alguma E / S estivesse esperando pelo processo, por que esperar o processo?

    
por 21.02.2011 / 06:04