2012-04-06 13 views
9

Digamos que llamo select() en un FD_SET que contiene un grupo de descriptores de archivos leídos. ¿Qué sucede si durante la llamada select(), se cierra uno de los descriptores de archivo? Suponiendo que se produce algún tipo de error, ¿es mi responsabilidad encontrar y eliminar el descriptor de archivo cerrado del conjunto?Unix: ¿Qué sucede cuando un descriptor de archivo de lectura se cierra durante la llamada? Select()

+0

Tenga en cuenta que la única forma posible de que un descriptor de archivo que reside en un fd_set mientras está dentro de la llamada select() se puede cerrar es si otro hilo cierra() ese descriptor. (Tener una conexión tcp cerrada por el par o su pila local tcp/ip es otro asunto). – nos

+0

Véase también http://stackoverflow.com/questions/3884110/what-is-select-supposed-to-do-if-y-close-a-monitored-fd –

Respuesta

4

No creo que esto esté especificado en ningún lado; algunos sistemas pueden regresar inmediatamente desde select mientras que otros pueden continuar bloqueando. Tenga en cuenta que la única forma en que esto puede suceder es en un proceso de subprocesos múltiples (de lo contrario, el close no puede ocurrir durante select; incluso si sucedió desde un manejador de señal, select ya habría sido interrumpido por la señal). Como tal, esta situación que surge probablemente indica que tiene problemas más importantes de los que preocuparse. Si uno de los descriptores de archivo que está encuestando puede cerrarse durante select, el problema mayor es que el mismo descriptor de archivo puede reasignarse a un archivo recién abierto (por ejemplo, uno abierto en otro hilo no relacionado) inmediatamente después del close, y el hilo es decir, es posible que la encuesta ejecute erróneamente IO en el nuevo archivo "perteneciente a" un hilo diferente.

Si tiene un objeto de datos que consta de un conjunto de descriptores de archivos que se sondearán con select en un programa multiproceso, seguramente necesitará utilizar algún tipo de primitiva de sincronización para controlar el acceso a ese conjunto, y agregar o eliminar los descriptores de archivos debe requerir un bloqueo que sea mutuamente exclusivo con la posibilidad de que select (o cualquier IO en los miembros) esté en progreso.

Por supuesto, en un programa de subprocesos múltiples, puede ser mejor no usar select en absoluto y en su lugar dejar que bloquee IO en múltiples subprocesos para lograr el resultado deseado sin complicada lógica de bloqueo.

1

La llamada al sistema select() tiene tres parámetros fd_set: Enviar, Recibir, Excepción. Para verificar, si se produce un error en un descriptor de archivo de lectura, inclúyalo en la lectura (recepción) y en el error (excepción) establecido, viéndolo en la excepción establecida en return from select() significa que ha ocurrido una excepción en ese socket, dando tienes la oportunidad de descubrir qué.

En general, los enchufes de red con cualquier tipo de excepción ya no serán aptos para enviar y recibir.

+0

En realidad, 'exceptfds' se usa para datos urgentes. – cnicutar

+0

http://linux.die.net/man/2/select, así como mi experiencia dice lo contrario: * "esos [descriptores de archivos] en exceptofds se verán en busca de excepciones" * –

+0

No me gusta promocionar mi respuesta, pero Agregué un enlace y una cita. – cnicutar

1

Incluso si ha leído todos los datos enviados, siempre se considera que una toma cerrada está lista para leer. Select se desbloqueará, indicando que el socket está disponible.

Cuestiones relacionadas