pipes - ¿Cómo funciona una tubería en Linux?
pipes linux c (4)
La tubería no completa el primer comando antes de ejecutar el segundo . La tubería Unix (y Linux) ejecuta todos los comandos simultáneamente. Un comando será suspendido si
Está hambriento de aportes.
Ha producido un rendimiento significativamente mayor de lo que su sucesor está listo para consumir.
Para la mayoría de los programas, la salida está almacenada en búfer , lo que significa que el sistema operativo acumula una cantidad sustancial de salida (tal vez 8000 caracteres más o menos) antes de pasarla a la siguiente etapa de la tubería. Este almacenamiento en búfer se usa para evitar demasiada conmutación entre procesos y kernel.
Si desea que la salida en una tubería sea enviada de inmediato, puede usar E / S sin búfer , que en C significa llamar a algo como fflush()
para asegurarse de que cualquier salida almacenada fflush()
se envíe inmediatamente al siguiente proceso. La entrada sin búfer también es posible, pero en general es innecesaria porque un proceso que está hambriento de entrada normalmente no espera un búfer completo sino que procesa cualquier entrada que pueda obtener.
Para aplicaciones típicas, no se recomienda la salida sin búfer; generalmente obtienes el mejor rendimiento con los valores predeterminados. Sin embargo, en su caso, cuando desee hacer gráficos dinámicos inmediatamente, el primer proceso tiene la información disponible, definitivamente desea utilizar la salida sin búfer. Si está utilizando C, fflush(stdout)
llamar a fflush(stdout)
cuando quiera que se envíe la salida.
¿Cómo funciona la tubería? Si ejecuto un programa a través de CLI y redirijo la salida a un archivo ¿podré canalizar ese archivo a otro programa mientras se está escribiendo?
Básicamente, cuando se escribe una línea en el archivo, me gustaría que se canalice inmediatamente a mi segunda aplicación (estoy tratando de dibujar dinámicamente un gráfico de un programa existente). Simplemente no estoy seguro si la tubería completa el primer comando antes de pasar al siguiente comando.
¡Cualquier retroalimentación sería muy apreciada!
Si desea redireccionar la salida de un programa a la entrada de otro, simplemente use una tubería simple:
program1 arg arg | program2 arg arg
Si desea guardar la salida de program1
en un archivo y canalizarlo en program2
, puede usar tee(1)
:
program1 arg arg | tee output-file | program2 arg arg
Todos los programas en una tubería se ejecutan simultáneamente. La mayoría de los programas suelen utilizar E / S de bloqueo : si cuando intentan leer su entrada y no hay nada, bloquean : es decir, se detienen, y el sistema operativo los deshabilita para que se ejecuten hasta que haya más entradas disponibles (para evitar comer) arriba de la CPU). De forma similar, si un programa que está en proceso está escribiendo datos más rápido de lo que un programa posterior puede leer, eventualmente el buffer de la tubería se llena y el escritor bloquea: el SO lo desasigna hasta que el lector vacía el buffer de la tubería y luego puede continuar escribiendo de nuevo.
EDITAR
Si desea utilizar la salida de program1
como los parámetros de línea de comandos, puede usar las comillas inversas o la sintaxis $()
:
# Runs "program1 arg", and uses the output as the command-line arguments for
# program2
program2 `program1 arg`
# Same as above
program2 $(program1 arg)
La sintaxis $()
debe ser preferida, ya que son más claras y pueden anidarse.
Si sus dos programas insisten en leer y escribir en archivos y no usan stdin / stdout, puede encontrar que puede usar un conducto con nombre en lugar de un archivo.
Cree un conducto con nombre con el comando mknod (1):
$ mknod /tmp/named-pipe p
Luego configure sus programas para leer y escribir en / tmp / named-pipe (use la ruta / nombre que considere apropiado).
En este caso, ambos programas se ejecutarán en paralelo, bloqueando según sea necesario cuando la tubería esté llena / vacía como se describe en las otras respuestas.
Si sus programas se están comunicando con stdin
y stdout
, asegúrese de estar llamando a fflush(stdout)
después de escribir o encontrar la forma de deshabilitar el buffer de IO estándar. La mejor referencia que puedo pensar que realmente describe cómo implementar mejor las canalizaciones en C / C ++ es la Programación avanzada en el entorno UNIX o la Programación de red UNIX: Volumen 2 . Probablemente también puedas comenzar con este artículo .