A partir de man select
int select(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout);
nfds é o descritor de arquivo com o número mais alto em qualquer um dos três conjuntos, mais 1.
Qual é o objetivo nfds
, quando já temos readfds
, writefds
e a exceptfds
partir da qual os descritores de arquivo podem ser determinados?
system-calls
file-descriptors
phunehehe
fonte
fonte
Respostas:
Em "Programação Avançada no Ambiente UNIX" , W. Richard Stevens diz que é uma otimização de desempenho:
(1ª edição, página 399)
Se você estiver fazendo algum tipo de programação de sistemas UNIX, o manual do APUE é altamente recomendado.
ATUALIZAR
Um
fd_set
é geralmente capaz de rastrear até 1024 descritores de arquivos.A maneira mais eficiente para controlar quais
fds
estão definidas para0
e que são definidas como1
seria uma bitset, de modo que cadafd_set
consistiria de 1024 bits.Em um sistema de 32 bits, um int longo (ou "palavra") é de 32 bits, o que significa que cada um
fd_set
é1024/32 = 32 palavras.
Se
nfds
for algo pequeno, como 8 ou 16, o que seria em muitas aplicações, ele precisa apenas olhar dentro da 1ª palavra, que deve ser claramente mais rápida do que dentro de 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 é
Meu palpite é que, porque o código tenta manter todos os argumentos nos registros , para que a CPU possa trabalhar neles mais rapidamente e, se tivesse que rastrear duas variáveis extras, a CPU talvez não tivesse registros suficientes.
Portanto, em outras palavras,
select
está expondo um detalhe de implementação para que seja mais rápido.fonte
Não tenho certeza, já que não sou um dos designers de select (), mas diria que é uma otimização de desempenho. A função de chamada sabe quantos descritores de arquivo ele coloca na leitura, gravação e exceto nos FDs; então, por que o kernel deve descobrir isso novamente?
Lembre-se de que no início dos anos 80, quando o select () foi introduzido, eles não tinham multi-gigaghertz, multi-processadores para trabalhar. Um VAX de 25 MHz foi bastante rápido. Além disso, você queria que o select () trabalhasse rapidamente, se pudesse: se alguma E / S estava aguardando o processo, por que esperar o processo?
fonte
nreadfds
,nwritefds
enexceptfds
não apenas umnfds
.nfds
possa entrar em um registro para acesso mais rápido. Se tivesse que rastrear três números, junto com todos os outros argumentos, talvez a CPU não tivesse registros suficientes. Obviamente, o kernel poderia ter criado seus próprios comnfds
base em suas 3 variáveis hipotéticas. Então, meu palpite é que está expondo um detalhe de implementação para obter eficiência.nfds
Argumentos separados trariam muito pouco ganho. Na maioria das vezes, o processo abriu muito poucos processos em relação aFD_SETSIZE
. Um caso típico pode ter (4,4,2) de 1024; fazer a verificação do kernel (4,4,4) é uma grande vitória sobre (1024,1024,1024), mas a otimização para (4,4,2) seria quase inútil.nfds
, ou ser preguiçoso e chamadaselect(FD_SETSIZE, ...)
, o que seria mais lento.)