2009-03-13 15 views
6

select() è definita come:Query Selezionare Sistema chiamata

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

NFDS rappresenta il più alto descrittore di file in tutte le date set più uno. Vorrei sapere perché sono necessari questi dati per select() quando sono disponibili le informazioni di fd_set.

Se i FD nel set dicono, 4, 8, 9, il valore di nfds sarebbe 10. Selezionerebbe() moniter fds 9,8,7,6,5,4?

risposta

8

Il problema è che fd_set non è davvero un "set" nel modo in cui stai pensando. Il dettaglio dietro le quinte è che l'implementazione di un fd_set è solo un intero usato come bitfield. In altre parole, l'esecuzione

fd_set foo; 
FD_CLEAR(&foo); 
FD_SET(&foo, 3); 

insiemi foo al valore decimale 8 - imposta il quarto meno singificant bit a 1 (ricordiamo che 0 è un descrittore valido).

FD_SET(&foo, 3); 

è equivalente a

foo |= (1 << 3); 

Quindi, al fine di scegliere di lavorare bene, ha bisogno di sapere quali bit del fd_set sono bit che ti stanno a cuore. Altrimenti non ci sarebbe modo di dire a zero un bit che è "dentro" l'insieme ma impostato su falso da un bit zero che è "non in" l'insieme.

Nell'esempio, un fd_set con 4, 8 e 9 set e n = 10 viene interpretato come "Un set con 10 voci (fds 0-9). Le voci 4, 8 e 9 sono vere (monitorarle). Le voci 1,2,3,5,6,7 sono false (non monitorarle). Qualsiasi valore fd maggiore di 9 non è semplicemente nel periodo impostato. "

+1

Ma il numero di bit in int è 32, ma come può monitorare qualsiasi fd con un valore maggiore di 31 – Poorna

+0

qualcuno può rispondere a questo commento? – euphoria83

+0

@Shishir: Posix definisce 'fd_set' come una struct. Gli interni sono definiti dall'implementazione, ma un'implementazione diffusa è che la struttura contenga una serie di long con abbastanza bit nell'array per coprire tutti i possibili fd. Questo funziona perché Posix richiede anche 'open' per restituire "il descrittore di file inutilizzato con il numero più basso". Quindi non si supererà il range dell'array se non si hanno i file FD_SETSIZE aperti. http://pubs.opengroup.org/onlinepubs/007904975/basedefs/sys/select.h.html – indiv

0

Seleziona monitor quegli FD che sono stati abilitati utilizzando la macro FD_SET. Se non si abilita alcun FD per il monitoraggio, selezionare() non ne monitora nessuno.

"NFDS" è sicuramente ridondante, ma è parte dell'interfaccia di select(), quindi è necessario usarlo :)

In ogni caso, se avete {4, 8, 9} nel set, imposta NF su 10 (come hai detto) e seleziona() monitora solo i tre FD 4, 8 e 9.

0

Probabilmente è un'ottimizzazione in modo che select non debba percorrere l'intero fd_set per trovare fuori quali descrittori sono effettivamente utilizzati. Senza questo parametro, select avrebbe sempre bisogno di guardare l'intero set per trovare quali descrittori sono effettivamente utilizzati nella chiamata, con il parametro, parte di quel lavoro può essere omesso.

Problemi correlati