Ich habe zwei einfache Programme: A
und B
. A
würde zuerst laufen, B
erhält dann das "stdout" von A
und verwendet es als "stdin". Angenommen, ich verwende ein GNU / Linux-Betriebssystem und der einfachste Weg, dies zu tun, wäre:
./A | ./B
Wenn ich diesen Befehl beschreiben müsste, würde ich sagen, dass es sich um einen Befehl handelt, der Eingaben (dh Lesevorgänge) von einem Produzenten ( A
) entgegennimmt und an einen Verbraucher ( B
) schreibt . Ist das eine korrekte Beschreibung? Vermisse ich etwas?
pipe
terminology
nihulus
quelle
quelle
Antworten:
Das einzige, was an Ihrer Frage als falsch auffällt, ist, dass Sie sagen
Tatsächlich würden beide Programme fast zur gleichen Zeit gestartet. Wenn es keine Eingabe für
B
den Leseversuch gibt, wird es blockiert, bis es eine Eingabe zum Lesen gibt. Wenn niemand die Ausgabe liestA
, werden die Schreibvorgänge blockiert, bis die Ausgabe gelesen wurde (ein Teil wird von der Pipe gepuffert).Das einzige, was die an einer Pipeline beteiligten Prozesse synchronisiert, ist die E / A, dh das Lesen und Schreiben über die Pipeline. Geschieht kein Schreiben oder Lesen, laufen die beiden Prozesse völlig unabhängig voneinander ab. Wenn einer das Lesen oder Schreiben des anderen ignoriert, wird der ignorierte Prozess blockiert und schließlich durch ein
SIGPIPE
Signal abgebrochen (wenn geschrieben wird) oder eine Dateiendebedingung in seinem Standardeingabestream abgerufen (wenn gelesen wird), wenn der andere Prozess beendet wird .Die idiomatische Art zu beschreiben
A | B
ist, dass es sich um eine Pipeline handelt, die zwei Programme enthält. Die Ausgabe, die auf der Standardausgabe des ersten Programms erzeugt wird, kann auf der Standardeingabe von der zweiten gelesen werden ("[die Ausgabe von]A
wird in [die Eingabe von] geleitetB
"). Die Shell übernimmt die erforderlichen Installationsarbeiten, um dies zu ermöglichen.Wenn Sie die Wörter "Verbraucher" und "Erzeuger" verwenden möchten, ist das vermutlich auch in Ordnung.
Die Tatsache, dass dies in C geschriebene Programme sind, ist nicht relevant. Die Tatsache, dass es sich um Linux, MacOS, OpenBSD oder AIX handelt, spielt keine Rolle.
quelle
mkfifo
Pipe zu erstellen, dann B im Hintergrund zu starten und A in die Pipe zu schreiben. Dies ist jedoch eine Fehlentscheidung, da der Effekt derselbe wäre.yes | sed 10q
Der Begriff, der normalerweise in der Dokumentation verwendet wird, ist "Pipeline", die aus einem oder mehreren Befehlen besteht. siehe POSIX-Definition Technisch gesehen sind das also zwei Befehle, zwei Unterprozesse für die Shell (entweder
fork()+exec()
'ed external commands' oder 'subshells').Wie für Produzent-Verbraucher Teil betrifft, kann die Pipeline nach diesem Muster beschrieben werden, da:
/proc/<pid>/fd
Verzeichnis).stdout
und Konsumenten lesen,stdin
als ob sie ein einzelnes Kommando ausführen würden, auch wenn sie ohne einander existieren können .Der Unterschied, den ich hier sehe, besteht darin, dass Shell-Befehle im Gegensatz zu Producer-Consumer in anderen Sprachen die Pufferung verwenden und stdout schreiben, sobald der Puffer gefüllt ist. Es wird jedoch nicht erwähnt, dass Producer-Consumer diese Regel befolgen muss - warten Sie nur, wenn die Warteschlange gefüllt oder verworfen ist Daten (was etwas anderes ist, was die Pipeline nicht tut).
quelle