¿Cuáles son las ventajas de usar una tubería con nombre sobre una tubería sin nombre?

51

Estaba revisando un conjunto de preguntas de entrevista que se hacen desde un administrador de Unix; Encontré un tema llamado "tubería con nombre".

Busqué en Google el tema; hasta cierto punto he podido entenderlo: - tubos con nombre || FIFO

Pero aún siento que me falta el conocimiento de cuándo usar este tipo particular de tubería. ¿Hay situaciones especiales en las que las tuberías sin nombre no funcionarían?

Ankit
fuente

Respuestas:

39

Las tuberías con nombre (fifo) tienen cuatro tres ventajas que se me ocurren:

  • no tiene que comenzar los procesos de lectura / escritura al mismo tiempo
  • puedes tener múltiples lectores / escritores que no necesitan ascendencia común
  • como archivo puedes controlar la propiedad y los permisos
  • son bidireccionales, las tuberías sin nombre pueden ser unidireccionales *

    *) Piense en una carcasa estándar de |tubería que es unidireccional, varios proyectiles ( ksh, zshy bash) también ofrecen coprocesses que permiten la comunicación bidireccional. POSIX trata las canalizaciones como half-duplex (es decir, cada lado solo puede leer o escribir), la pipe()llamada al sistema devuelve dos identificadores de archivo y es posible que deba tratar uno como de solo lectura y el otro como de solo escritura. Algunos sistemas (BSD) admiten lectura y escritura simultáneas (no prohibidas por POSIX), en otros necesitaría dos tuberías, una para cada dirección. Consulte sus páginas de manual pipe(), popen()y posiblemente las de popen2()manual. La falta de direccionalidad puede no depender de si la tubería se nombra o no, aunque en Linux 2.6 depende.

(Actualizado, gracias a los comentarios de Stephane Chazelas )

Entonces, una tarea inmediatamente obvia que no puede lograr con una tubería sin nombre es una aplicación cliente / servidor convencional.

El último punto (marcado) sobre las tuberías unidireccionales es relevante en Linux, POSIX (ver popen()) dice que una tubería solo necesita ser legible o escribible , en Linux son unidireccionales . Consulte Comprender el kernel de Linux (3ª Ed. O'Reilly) para obtener detalles específicos de Linux (p787). Otros sistemas operativos ofrecen tuberías bidireccionales (sin nombre).

Como ejemplo, Nagios usa un fifo para su archivo de comando . Varios procesos externos (scripts CGI, comprobaciones externas, NRPE, etc.) escriben comandos / actualizaciones en este Fifo y estos son procesados ​​por el proceso persistente de Nagios.

Las canalizaciones con nombre tienen características similares a las conexiones TCP, pero existen diferencias importantes. Debido a que un Fifo tiene un nombre de sistema de archivos persistente, puede escribir en él incluso cuando no hay lector, es cierto que las escrituras se bloquearán (sin E / S asíncrona o sin bloqueo), aunque no perderá datos si el receptor no está iniciado (o se está reiniciando).

Como referencia, consulte también los sockets de dominio de Unix y la respuesta a esta pregunta de Stackoverflow que resume los principales métodos de IPC , y este que habla sobrepopen()

Sr. púrpura
fuente
2
también puede tener múltiples lectores / escritores con canalizaciones sin nombre. En Linux, no son más bidireccionales que las tuberías sin nombre. Hay un final de escritura y un final de lectura y los datos fluyen en una sola dirección. Cuando abre un fifo en modo de escritura, obtiene el final de escritura, en modo de lectura el final de lectura, en modo rw, escribe en el final de escritura y lee desde la lectura. Eso es diferente de las tuberías bidireccionales o los sockets de dominio Unix, donde en realidad tiene dos flujos de datos separados en cada dirección.
Stéphane Chazelas
@StephaneChazelas gracias por los comentarios, he actualizado la respuesta para ser más específica y aclarar (espero) las tuberías y la direccionalidad.
Sr.Spuratic
¿La comunicación a una tubería con nombre involucra disco IO? ¿O todo está en la memoria? ¿Qué determina el rendimiento de estos mecanismos de IPC?
CMCDragonkai
15

Las canalizaciones anónimas o sin nombre proporcionan un medio de comunicación interproceso unidireccional entre procesos diferentes que están relacionados por una relación padre-hijo o por ser hijos de un padre común que proporciona la canalización, como un shell proceso. Debido a que los procesos están relacionados, la asociación de descriptores de archivo a la tubería puede ser implícita y no requiere un objeto con un nombre que sea externo a los procesos. Una tubería sin nombre solo existe mientras los procesos que la usan mantengan descriptores de archivo abiertos en la tubería. Cuando los procesos salen y el sistema operativo cierra todos los descriptores de archivo asociados con los procesos, se cierra la tubería sin nombre.

Las tuberías con nombre son de hecho FIFO. Estos son objetos persistentes representados por nodos en el sistema de archivos. Una canalización con nombre proporciona una comunicación bidireccional de muchos a muchos entre uno o más procesos que no están necesariamente relacionados y no es necesario que existan al mismo tiempo. El nombre del archivo de la tubería sirve como una dirección o contrato entre los procesos de comunicación. Si solo un proceso escribe en una tubería con nombre y otro proceso lee de la tubería con nombre, entonces la tubería con nombre se comporta de la misma manera que una tubería sin nombre entre los dos procesos relacionados.

Entonces, la respuesta corta es que necesita una canalización con nombre para la comunicación entre procesos no relacionados que pueden no existir al mismo tiempo.

Jonathan Ben-Avraham
fuente
+1 Creo que los procesos casi siempre existen al mismo tiempo (de lo contrario, la tubería es un poco inútil, también podría dejar cosas en un archivo normal). Estos y los sockets de dominio de Unix a menudo son utilizados por los servicios de daemon que pueden controlarse, por ejemplo, desde la línea de comandos. Si observa /runun sistema de escritorio de Linux, probablemente encontrará algunos de los dos (denominados enchufes fifos y unix). Es una forma de IPC .
Ricitos de oro
2
@goldilocks: una canalización con nombre se usa comúnmente como un buzón ad-hoc residente en memoria entre procesos en sistemas integrados, donde los procesos de comunicación son de corta duración y no existen al mismo tiempo. La ventaja es la simplicidad de la implementación frente a la memoria compartida IPC y el hecho de que solo se usa RAM. La desventaja es la no persistencia entre las botas y la naturaleza FIFO en bytes de la tubería versus la capacidad de usar una estructura con memoria compartida.
Jonathan Ben-Avraham
@ Jonathan: +1, tengo algunas dudas: - ¿Por qué nos referimos a las tuberías con nombre como FIFO? ¿Qué son los objetos persistentes?
Ankit
@Ankit: Algunas personas llaman a una tubería con nombre FIFO porque se comporta como una estructura de datos FIFO, especialmente cuando se abre para leer y escribir mediante un solo proceso. Por "objeto persistente" quise decir que una tubería con nombre está asociada con un objeto del sistema de archivos. Es decir, es un tipo de archivo, con un nombre, y tiene la misma persistencia que cualquier otro archivo almacenado en los medios.
Jonathan Ben-Avraham
4

Una ventaja que no se menciona en otra parte es que una tubería con nombre se puede usar en lugares donde solo funcionará un archivo.

Por ejemplo, algunos clientes de correo electrónico tienen la función de agregar el contenido de ~ / .signature a cada mensaje de correo. Si .signature fuera una opción de línea de comandos o si el cliente de correo pudiera notar que .signature es ejecutable y ejecutarlo, entonces no necesitaría una canalización con nombre. Pero si el cliente de correo no es tan sofisticado, puede crear una tubería con nombre llamada .signature y ejecutar una aplicación que genere una nueva firma cada vez que se lea el archivo.

Eyal
fuente
Interesante. ¿Tienes tal aplicación? Parece que tendría que mirar a nivel del núcleo para ver cuándo se accedía al FIFO.
Comodín el
4

Hay otra ventaja de las canalizaciones con nombre: puede usarlas en diferentes sistemas . Suponga que desea una comunicación en tiempo real de dos procesos que se ejecutan en máquinas diferentes. Luego comparta una carpeta entre los dos, coloque su FIFO en la carpeta y listo. Es considerablemente más fácil que transformar una aplicación diseñada para trabajar en archivos en un servicio que escucha en un puerto.

MariusMatutiae
fuente