2012-08-06 12 views
10

Tengo este escenario siguiente.¿Necesitamos cerrar el extremo de lectura de una tubería explícitamente cuyo final de escritura ya se ha cerrado?

  1. Creo una tubería.

  2. Bifurcó un proceso de niño.

  3. niño cierra leer extremo de la tubería de manera explícita y escribe en el extremo de escritura de la tubería y salidas sin cerrar nada (salida debe cerrar todos los descriptores de archivo/tuberías abiertas en nombre del niño, supongo).

  4. Padres cierra el extremo de escritura de la tubería de manera explícita y lee desde la lectura final de la tubería usando fgets hasta fgets devuelve null. es decir, lee completamente.

Ahora mi pregunta es, ¿por qué el padre tiene que cerrar el extremo de lectura de la tubería explícitamente una vez que ha terminado de leer? ¿No es prudente que el sistema elimine el conducto por completo una vez que se han leído los datos completos desde el extremo de lectura?

No cierre el extremo de lectura explícitamente en el elemento primario y tarde o temprano tengo Too many file descriptors error mientras abro más tuberías. Mi suposición era que el sistema elimina automáticamente una tubería una vez que su final de escritura se cierra y los datos han sido completamente leídos desde el final de lectura. Porque no puedes de una pipa dos veces!

Entonces, ¿cuál es la razón detrás del sistema que no elimina la tubería una vez que los datos han sido completamente leídos y cerrados?

+0

"¡Porque no puedes cantar dos veces!" ??? –

+0

@KerrekSB Lo que quise decir es que puede leer la misma tubería dos veces pero verá EOF por segunda vez, ¿verdad? –

Respuesta

7

Tiene la razón de que el sistema cerrará el extremo de escritura de la tubería una vez que el niño haya salido. Sin embargo, podría haber otro final de escritura de ese conducto abierto, si el hijo fork o pasa un duplicado del final de escritura a otro proceso.

Todavía es cierto que el sistema podría decir cuándo se han cerrado todas las descripciones en un extremo de una tubería (explícitamente o porque el proceso de propiedad se ha cerrado). Todavía no tiene sentido cerrar los que están en el otro extremo de la tubería, ya que eso generaría confusión cuando el proceso principal intente cerrar el descriptor en su extremo de la tubería; ya sea:

  • fd ha sido cerrado por el sistema, en cuyo caso hay un error al intentar cerrar un fd ya cerrado; o
  • el fd ha sido reutilizado, lo que es aún peor ya que ahora está cerrando un fd completamente sin relación.

Desde el punto de vista del sistema, bien podría haber descartado la tubería una vez que se hayan cerrado todas las descripciones en un extremo, por lo que no tiene que preocuparse por la ineficiencia. Lo que más importa es que el proceso de espacio del usuario debe tener una experiencia consistente, lo que significa no cerrar el descriptor a menos que se solicite específicamente.

5

Los descriptores de archivo no se cierran por el sistema, hasta que el proceso finaliza. Esto es cierto para las tuberías, así como para cualquier otro descriptor de archivo.

Hay una gran diferencia entre una tubería (o cualquier otro archivo) sin datos y un descriptor de archivo cerrado.
Cuando se cierra un descriptor de archivo, el sistema puede reutilizar su número para un nuevo descriptor de archivo. Luego, cuando lees, obtienes algo más. Luego de que haya cerrado un descriptor de archivo, ya no debe usarlo.

Ahora imagine que una vez que no hay más datos, el sistema cerrará automáticamente el descriptor del archivo. Esto haría que el número esté disponible para su reutilización, y una subsiguiente apertura no relacionada puede obtenerlo. Ahora el lector, que aún no sabe que no hay más datos, leerá lo que cree que es el conducto, pero leerá de otro archivo.

Cuestiones relacionadas