¿Por qué usar una tubería con nombre en lugar de un archivo?

42

Hace poco leí sobre tuberías con nombre, y no podía entender por qué existen.
He leído en alguna parte que usar una tubería con nombre lleva menos tiempo que usar un archivo.

¿Por qué esto es tan?
Las canalizaciones con nombre también deben almacenarse en la memoria (y tal vez intercambiarse, al igual que los archivos).
Por lo que puedo ver, deben obtener un inodo al que debe hacer referencia el directorio actual, al igual que los archivos. Además, el programador debe eliminarlos, al igual que los archivos.

Entonces, ¿dónde radica la ventaja?

usuario3122885
fuente
Esto no es parte de una tarea de clase, ¿verdad?
don.joey
66
no ... en realidad estaba revisando algunas notas de clase cuando encontré esta pregunta y no pude responderla ... y si fuera una tarea, no veo cómo eso sería relevante ... no es como No buscaría la respuesta hasta encontrarla
user3122885

Respuestas:

41

Casi todo en Linux puede considerarse un archivo , pero la principal diferencia entre un archivo normal y una canalización con nombre es que una canalización con nombre es una instancia especial de un archivo que no tiene contenido en el sistema de archivos.

Aquí hay una cita de man fifo:

Un archivo especial FIFO (una tubería con nombre) es similar a una tubería, excepto que se accede como parte del sistema de archivos. Puede abrirse mediante múltiples procesos para leer o escribir. Cuando los procesos intercambian datos a través de FIFO, el núcleo pasa todos los datos internamente sin escribirlos en el sistema de archivos. Por lo tanto, el archivo especial FIFO no tiene contenido en el sistema de archivos; la entrada del sistema de archivos simplemente sirve como punto de referencia para que los procesos puedan acceder a la tubería utilizando un nombre en el sistema de archivos.

El núcleo mantiene exactamente un objeto de tubería para cada archivo especial FIFO que se abre al menos por un proceso. El FIFO debe abrirse en ambos extremos (lectura y escritura) antes de que se puedan pasar los datos. Normalmente, abrir los bloques FIFO hasta que el otro extremo también se abra.

Entonces, en realidad, una tubería con nombre no hace nada hasta que algún proceso lo lee y escribe. No ocupa espacio en el disco duro (excepto un poco de metainformación), no utiliza la CPU.

Puede verificarlo haciendo esto:

Crear una tubería con nombre

$ mkfifo /tmp/testpipe

Vaya a algún directorio, por ejemplo /home/user/Documents, y gzip todo lo que contiene, usando una tubería con nombre.

$ cd /home/user/Documents
$ tar cvf - . | gzip > /tmp/testpipe &
[1] 28584

Aquí debería ver el PID del proceso gzip. En nuestro ejemplo fue 28584.

Ahora verifique qué está haciendo este PID

$ ps u -P 28584
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
c0rp     28584  0.0  0.0  29276  7800 pts/8    S    00:08   0:00 bash

Verá que no está utilizando recursos . 0% de uso de CPU, 0% de uso de memoria.

Verifique el presentimiento sobre el uso del espacio de archivos

$ du -h /tmp/testpipe
0   testpipe

Y de nuevo 0, nada. El tubo de ensayo podría usarse nuevamente si fuera necesario.

No te olvides de matar a gzip, usando kill -15 28584. Y quite nuestra tubería con nombre usandorm /tmp/testpipe

Usos de ejemplo

Puede redirigir casi todo utilizando una canalización con nombre. Como ejemplo, puede ver este proxy de una línea .

También aquí hay una buena explicación más del uso de tuberías con nombre. Puede configurar dos procesos en un servidor para comunicarse utilizando una tubería con nombre en lugar de la pila TCP / IP. Es mucho más rápido y no carga recursos de red. Por ejemplo, su servidor web puede comunicarse con la base de datos directamente usando una tubería con nombre, en lugar de usar la localhostdirección o escuchar algún puerto.

c0rp
fuente
14

Es cierto que no usará la memoria del sistema, pero el hecho de que no use CPU en su ejemplo es solo porque no lee la tubería, por lo que el proceso está esperando.

Considere el siguiente ejemplo:

mkfifo /tmp/testpipe
tar cvf - / | gzip > /tmp/testpipe

Ahora abra una nueva consola y ejecute:

watch -n 1 'ps u -P $(pidof tar)

Y en una tercera consola:

cat /tmp/testpipe > /dev/null

Si observa el cmd del reloj (segundo término), ¡mostrará un aumento en el consumo de CPU!

GARCIN David
fuente
1
Esta respuesta es sobre la respuesta de
c0rp
2

Aquí hay un caso de uso en el que las canalizaciones con nombre pueden ahorrarle mucho tiempo al eliminar las E / S.

Supongamos que tiene un BigFile, por ejemplo 10G.

También tiene divisiones de este BigFile en piezas de 1G, BigFileSplit_01 a BigFile_Split_10.

Ahora tiene una duda sobre la corrección de BigFileSplit_05

Ingenuamente, sin canalizaciones con nombre, crearía una nueva división de BigFile y compararía:

dd if=BigFile of=BigFileSplitOrig_05 bs=1G skip=4 count=1
diff -s BigFileSplitOrig_05 BigFileSplit_05
rm BigFileSplitOrig_05

Con tuberías con nombre harías

mkfifo BigFileSplitOrig_05
dd if=BigFile of=BigFileSplitOrig_05 bs=1G skip=4 count=1 &
diff -s BigFileSplitOrig_05 BigFileSplit_05
rm BigFileSplitOrig_05

A primera vista, eso puede no parecer una gran diferencia ... ¡pero con el tiempo la diferencia es enorme!

Opción 1:

  • dd: leer 1G / escribir 1G (1)
  • diff: leer 2G
  • rm: clústeres asignados gratis / eliminar entrada de directorio

Opcion 2:

  • dd: nada! (va a la tubería con nombre)
  • diff: leer 2G
  • rm: no hay clúster asignado para administrar (en realidad no escribimos nada en el sistema de archivos) / eliminar la entrada del directorio

Entonces, básicamente, la tubería con nombre le ahorra aquí una lectura y escritura de 1G más una limpieza del sistema de archivos (ya que no escribimos nada en el sistema de archivos excepto el nodo vacío de Fifo).

No hacer E / S, especialmente las escrituras, también es bueno para evitar el desgaste de sus discos. Es aún más interesante cuando trabaja con SSD, ya que tienen un número limitado de escrituras antes de que las células mueran.

(1) Obviamente, otra opción sería crear ese archivo temporal en RAM, por ejemplo si / tmp está montado en RAM (tmpfs). Sin embargo, estaría limitado por el tamaño del disco RAM, mientras que el "truco de la tubería con nombre" no tiene límites.

Zakhar
fuente
1

Puede dejar que un programa permanezca quieto y escuchar una canalización con nombre para algún evento externo. Tan pronto como ocurra el evento externo (por ejemplo, la llegada de algunos datos nuevos) esto podría ser detectado por otro programa que a su vez abre la tubería para escribir, escribiendo los datos de eventos relevantes en la tubería. Cuando se emite la declaración de cierre, el programa de escucha recibirá el flujo de datos a través de la tubería a través de una declaración de lectura, y está listo para procesar lo que tiene. No olvide cerrar la tubería después de leer el contenido. El programa de escucha también podría devolver resultados de su procesamiento a través del mismo, o a través de otra tubería con nombre. Tales comunicaciones entre programas son muy convenientes a veces.

Por Anton Ronning
fuente