De man select
int select(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout);
nfds est le descripteur de fichier le plus numéroté dans l'un des trois ensembles, plus 1.
À quoi sert nfds
, lorsque nous en avons déjà readfds
, writefds
et à exceptfds
partir duquel les descripteurs de fichiers peuvent être déterminés?
system-calls
file-descriptors
phunehehe
la source
la source
Réponses:
Dans "Programmation avancée dans l'environnement UNIX" , W. Richard Stevens dit qu'il s'agit d'une optimisation des performances:
(1ère édition, page 399)
Si vous faites n'importe quel type de programmation de systèmes UNIX, le livre APUE est fortement recommandé.
MISE À JOUR
An
fd_set
est généralement capable de suivre jusqu'à 1024 descripteurs de fichiers.Le moyen le plus efficace de suivre ceux qui
fds
sont définis0
et ceux qui sont définis1
serait un jeu de bits, donc chacunfd_set
serait composé de 1024 bits.Sur un système 32 bits, un entier long (ou "mot") est de 32 bits, ce qui signifie que chacun
fd_set
est1024/32 = 32 mots.
S'il
nfds
s'agit de quelque chose de petit, comme 8 ou 16, qu'il serait dans de nombreuses applications, il suffit de regarder à l'intérieur du premier mot, qui devrait clairement être plus rapide que de regarder à l'intérieur des 32.(Voir
FD_SETSIZE
et à__NFDBITS
partir/usr/include/sys/select.h
des valeurs sur votre plate-forme.)MISE À JOUR 2
Quant à savoir pourquoi la signature de fonction n'est pas
Je suppose que c'est parce que le code essaie de conserver tous les arguments dans les registres , de sorte que le processeur peut travailler plus rapidement sur eux, et s'il devait suivre 2 variables supplémentaires, le processeur pourrait ne pas avoir suffisamment de registres.
En d'autres termes,
select
expose un détail d'implémentation afin qu'il puisse être plus rapide.la source
Je ne suis pas sûr, car je ne suis pas l'un des concepteurs de select (), mais je dirais que c'est une optimisation des performances. La fonction appelante sait combien de descripteurs de fichiers elle a mis dans les FD en lecture, en écriture et à l'exception, alors pourquoi le noyau devrait-il le retrouver?
Rappelez-vous qu'au début des années 80, lorsque select () a été introduit, ils n'avaient pas de multi-gigaghertz, multi-processeurs avec lesquels travailler. Un VAX à 25 MHz était assez rapide. De plus, vous vouliez que select () fonctionne rapidement s'il le pouvait: si des E / S attendaient le processus, pourquoi le faire attendre?
la source
nreadfds
,nwritefds
etnexceptfds
au lieu d'un seulnfds
.nfds
pouvoir aller dans un registre pour un accès plus rapide. S'il devait suivre trois nombres, ainsi que tous les autres arguments, le processeur n'aurait peut-être pas suffisamment de registres. Bien sûr, le noyau aurait pu créer le sien ennfds
fonction de vos 3 variables hypothétiques. Donc, je suppose qu'il expose un détail d'implémentation pour gagner en efficacité.nfds
arguments séparés apporteraient très peu de gain. La plupart du temps, le processus a ouvert très peu de processus par rapport àFD_SETSIZE
. Un cas typique pourrait avoir (4,4,2) sur 1024; effectuer la vérification du noyau (4,4,4) est une grosse victoire (1024,1024,1024), mais l'optimisation jusqu'à (4,4,2) serait presque inutile.nfds
, ou être paresseux et appelerselect(FD_SETSIZE, ...)
, ce qui serait plus lent.)