2009-03-13 9 views
6

select() se define como llamadas al sistema:consulta en Seleccionar

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

nfds representa el descriptor de archivo más alto de todos los conjuntos dados más uno. Me gustaría saber por qué se requieren estos datos para select() cuando la información de fd_set está disponible.

Si se dicen el FDS en el conjunto, 4, 8, 9, el valor de nfds habría 10. seleccionaría() moniter FDS 9,8,7,6,5,4?

Respuesta

8

El problema es que fd_set no es realmente un "conjunto" en la forma en que estás pensando. El detalle entre bastidores es que la implementación de un fd_set es solo un entero que se usa como campo de bits. En otras palabras, la ejecución de

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

Conjuntos foo a valor decimal 8 - se establece el cuarto-menos-singificant bit a 1 (recuerde que 0 es un descriptor válido).

FD_SET(&foo, 3); 

es equivalente a

foo |= (1 << 3); 

Así que para que seleccione a trabajar a la derecha, lo que necesita saber qué bits de la fd_set son bits que le interesan. De lo contrario, no habría forma de que diga un bit cero que está "en" el conjunto pero configurado en falso desde un bit cero que "no está en" el conjunto.

En su ejemplo, un fd_set con 4, 8 y 9 conjunto yn = 10 se interpreta como "Un conjunto con 10 entradas (fds 0-9). Las entradas 4, 8 y 9 son verdaderas (supervisarlas)). Las entradas 1,2,3,5,6,7 son falsas (no las controle). Cualquier valor fd mayor que 9 simplemente no está en el período establecido. "

+1

Pero el número de bits en int es 32, pero ¿cómo puede controlar cualquier fd con un valor mayor que 31 – Poorna

+0

¿alguien puede responder este comentario? – euphoria83

+0

@Shishir: Posix define 'fd_set' como una estructura. Las partes internas están definidas por la implementación, pero una implementación popular es que la estructura contenga una matriz de longs con suficientes bits en la matriz para cubrir todos los fd posibles. Esto funciona porque Posix también requiere 'abrir' para devolver" el descriptor de archivo no utilizado con el número más bajo ". Por lo tanto, no excederá el rango de la matriz a menos que tenga archivos FD_SETSIZE abiertos. http://pubs.opengroup.org/onlinepubs/007904975/basedefs/sys/select.h.html – indiv

0

Seleccione monitorea los FD que ha habilitado utilizando la macro FD_SET. Si no habilita ningún FD para la supervisión, seleccione() no supervisa ninguno.

"nfds" es definitivamente redundante, pero es parte de la interfaz de selección(), por lo que necesita para usarlo :)

De todos modos, si usted tiene {4, 8, 9} en el conjunto, establece nfds en 10 (como mencionó), y seleccione() solo controlará los tres FD 4, 8 y 9.

0

Probablemente sea una optimización para que no tenga que recorrer toda la fd_set para encontrar qué descriptores se usan realmente Sin ese parámetro, select siempre tendría que mirar todo el conjunto para encontrar qué descripciones se usan realmente en la llamada, con el parámetro, se puede omitir parte de ese trabajo.

Cuestiones relacionadas