Tengo dos programas simples: A
y B
. A
correría primero, luego B
obtiene el "stdout" de A
y lo usa como su "stdin". Suponga que estoy usando un sistema operativo GNU / Linux y la forma más simple de hacerlo sería:
./A | ./B
Si tuviera que describir este comando, diría que es un comando que toma información (es decir, lee) de un productor ( A
) y escribe a un consumidor ( B
). ¿Es esa una descripción correcta? ¿Me estoy perdiendo algo?
pipe
terminology
nihulus
fuente
fuente
Respuestas:
Lo único sobre su pregunta que se destaca como incorrecto es que usted dice
De hecho, ambos programas se iniciarían casi al mismo tiempo. Si no hay entrada para
B
cuando intenta leer, se bloqueará hasta que haya entrada para leer. Del mismo modo, si no hay nadie que lea la salidaA
, sus escrituras se bloquearán hasta que se lea su salida (parte de la tubería se amortiguará).Lo único que sincroniza los procesos que participan en una tubería es la E / S, es decir, la lectura y escritura a través de la tubería. Si no ocurre escritura o lectura, entonces los dos procesos se ejecutarán de manera totalmente independiente el uno del otro. Si uno ignora la lectura o escritura del otro, el proceso ignorado se bloqueará y eventualmente será eliminado por una
SIGPIPE
señal (si está escribiendo) u obtendrá una condición de fin de archivo en su flujo de entrada estándar (si está leyendo) cuando el otro proceso finalice .La forma idiomática de describir
A | B
es que es una tubería que contiene dos programas. La salida producida en la salida estándar del primer programa está disponible para ser leída en la entrada estándar por el segundo ("[la salida de]A
se canaliza a [la entrada de]B
"). El shell realiza las tuberías necesarias para permitir que esto suceda.Si desea utilizar las palabras "consumidor" y "productor", supongo que también está bien.
El hecho de que se trate de programas escritos en C no es relevante. El hecho de que esto sea Linux, macOS, OpenBSD o AIX no es relevante.
fuente
mkfifo
para crear una tubería con nombre, luego comenzar B en la lectura de fondo de la tubería y luego A escribir en ella. Sin embargo, esto es difícil, ya que el efecto sería el mismo.yes | sed 10q
El término generalmente utilizado en la documentación es "canalización", que consiste en uno o más comandos, consulte la definición POSIX. Técnicamente hablando, son dos comandos que tiene allí, dos subprocesos para el shell (
fork()+exec()
comandos externos o subcapas)En cuanto a la parte productor-consumidor , la tubería se puede describir por ese patrón, ya que:
/proc/<pid>/fd
directorio).stdout
y los consumidores leenstdin
como si se tratara de un solo comando en ejecución, es decir, pueden existir el uno sin el otro .La diferencia que veo aquí es que, a diferencia de Producer-Consumer en otros idiomas, los comandos de shell usan el almacenamiento en búfer y escriben stdout una vez que se llena el búfer, pero no se menciona que Producer-Consumer tenga que seguir esa regla: solo espere cuando la cola esté llena o descarte datos (que es algo más que la tubería no hace).
fuente