Warum eine Named Pipe anstelle einer Datei verwenden?

42

Ich habe kürzlich über Named Pipes gelesen und konnte nicht verstehen, warum sie existieren.
Ich habe irgendwo gelesen, dass die Verwendung einer Named Pipe weniger zeitaufwendig ist als die Verwendung einer Datei.

Warum ist das so?
Die Named Pipes müssen ebenfalls im Speicher abgelegt werden (und können wie Dateien ausgetauscht werden).
Soweit ich sehen kann, müssen sie eine Inode erhalten, auf die vom aktuellen Verzeichnis verwiesen werden muss, genau wie auf Dateien. Sie müssen ebenso wie Dateien vom Programmierer entfernt werden.

Wo liegt also der Vorteil?

user3122885
quelle
Dies ist nicht Teil einer Klassenaufgabe, oder?
don.joey
6
nein ... eigentlich habe ich einige Vorlesungsunterlagen durchgesehen, als ich diese Frage gefunden habe und ich konnte sie nicht beantworten ... und wenn es eine Aufgabe wäre, dann sehe ich nicht, wie relevant das wäre ... es ist nicht so Ich würde nicht nach der Antwort suchen, bis ich sie finden würde
user3122885

Antworten:

41

Fast alles in Linux kann als Datei betrachtet werden. Der Hauptunterschied zwischen einer regulären Datei und einer Named Pipe besteht darin, dass eine Named Pipe eine spezielle Instanz einer Datei ist, die keinen Inhalt im Dateisystem hat.

Hier ist ein Zitat aus man fifo:

Eine FIFO-Spezialdatei (eine Named Pipe) ähnelt einer Pipe mit dem Unterschied, dass auf sie als Teil des Dateisystems zugegriffen wird. Es kann durch mehrere Prozesse zum Lesen oder Schreiben geöffnet werden. Wenn Prozesse Daten über das FIFO austauschen, leitet der Kernel alle Daten intern weiter, ohne sie in das Dateisystem zu schreiben. Somit hat die FIFO-Spezialdatei keinen Inhalt im Dateisystem; Der Dateisystemeintrag dient lediglich als Referenzpunkt, sodass Prozesse über einen Namen im Dateisystem auf die Pipe zugreifen können.

Der Kernel verwaltet genau ein Pipe-Objekt für jede FIFO-Spezialdatei, die von mindestens einem Prozess geöffnet wird. Der FIFO muss an beiden Enden geöffnet sein (Lesen und Schreiben), bevor Daten übertragen werden können. Normalerweise werden die FIFO-Blöcke geöffnet, bis auch das andere Ende geöffnet ist.

Tatsächlich tut eine Named Pipe also nichts, bis ein Prozess darauf liest und schreibt. Es nimmt keinen Platz auf der Festplatte ein (außer ein bisschen Metainformationen), es verwendet nicht die CPU.

Sie können dies folgendermaßen überprüfen:

Erstellen Sie eine Named Pipe

$ mkfifo /tmp/testpipe

Gehen Sie zum Beispiel in ein Verzeichnis /home/user/Documentsund gzipen Sie alles darin mit der Named Pipe.

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

Hier sollte die PID des gzip-Prozesses angezeigt werden. In unserem Beispiel war es 28584.

Überprüfen Sie nun, was diese PID tut

$ 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

Sie werden sehen, dass keine Ressourcen verwendet werden . 0% CPU-Auslastung, 0% Speicherauslastung.

Überprüfen Sie die Größe des Dateibereichs

$ du -h /tmp/testpipe
0   testpipe

Und wieder 0nichts. Die Testpipe kann bei Bedarf wieder verwendet werden.

Vergiss nicht, gzip mit zu töten kill -15 28584. Und entfernen Sie unsere Named Pipe mitrm /tmp/testpipe

Beispielanwendungen

Sie können fast alles mit Named Pipe umleiten. Als Beispiel sehen Sie diesen einzeiligen Proxy .

Auch hier gibt es noch eine nette Erklärung für die Verwendung von Named Pipes. Sie können zwei Prozesse auf einem Server so konfigurieren, dass die Kommunikation über eine Named Pipe anstelle des TCP / IP-Stacks erfolgt. Es ist viel schneller und lädt keine Netzwerkressourcen. Beispielsweise kann Ihr Webserver direkt über eine Named Pipe mit der Datenbank kommunizieren, anstatt die localhostAdresse zu verwenden oder einen Port abzuhören.

c0rp
quelle
14

Es ist wahr, dass Sie keinen Systemspeicher verwenden, aber die Tatsache, dass Sie in Ihrem Beispiel keine CPU verwenden, liegt nur daran, dass Sie die Pipe nicht lesen und der Prozess wartet.

Betrachten Sie folgendes Beispiel:

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

Öffnen Sie nun eine neue Konsole und führen Sie Folgendes aus:

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

Und in einer dritten Konsole:

cat /tmp/testpipe > /dev/null

Wenn Sie sich die Uhr cmd (2. Semester) ansehen, wird sie einen Anstieg des CPU-Verbrauchs anzeigen!

GARCIN David
quelle
1
Bei dieser Antwort handelt es sich um die Antwort von
c0rp
2

In diesem Anwendungsfall können Named Pipes durch das Entfernen von E / A viel Zeit sparen.

Nehmen wir an, Sie haben eine BigFile, zum Beispiel 10G.

Sie haben auch Teilungen dieses BigFile in Teilen von 1G, BigFileSplit_01 bis BigFile_Split_10.

Jetzt haben Sie Zweifel an der Richtigkeit von BigFileSplit_05

Naiv würden Sie ohne Named Pipes einen neuen Split von BigFile erstellen und Folgendes vergleichen:

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

Mit Named Pipes würden Sie tun

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

Das mag auf den ersten Blick nicht als großer Unterschied erscheinen ... aber mit der Zeit ist der Unterschied riesig!

Option 1:

  • dd: 1G lesen / 1G schreiben (1)
  • diff: lies 2G
  • rm: frei zugewiesene Cluster / Verzeichniseintrag entfernen

Option 2:

  • dd: nichts! (geht zur Named Pipe)
  • diff: lies 2G
  • rm: Kein zugeteilter Cluster zum Verwalten (wir haben eigentlich nichts in das Dateisystem geschrieben) / Verzeichniseintrag entfernen

Im Grunde erspart Ihnen die Named Pipe hier das Lesen und Schreiben von 1G sowie einige Dateisystembereinigungen (da wir nichts in das Dateisystem geschrieben haben, sondern nur den leeren FIFO-Knoten).

Wenn Sie keine E / A-Vorgänge ausführen, insbesondere keine Schreibvorgänge, können Sie auch den Verschleiß Ihrer Datenträger vermeiden. Es ist sogar noch interessanter, wenn Sie mit SSDs arbeiten, da diese eine begrenzte Anzahl von Schreibvorgängen haben, bevor die Zellen absterben.

(1) Eine andere Möglichkeit wäre natürlich, diese temporäre Datei im RAM zu erstellen, zum Beispiel wenn / tmp im RAM gemountet ist (tmpfs). Trotzdem wären Sie durch die Größe der RAM-Disk begrenzt, wohingegen der "Named-Pipe-Trick" keine Grenzen kennt.

Zakhar
quelle
0

Sie können ein Programm ruhig liegen lassen und eine Named Pipe für ein externes Ereignis abhören. Sobald das äußere Ereignis eintritt (z. B. das Eintreffen neuer Daten), könnte dies von einem anderen Programm erkannt werden, das seinerseits die Pipe zum Schreiben öffnet und die relevanten Ereignisdaten in die Pipe schreibt. Wenn die close-Anweisung ausgegeben wird, empfängt das Listening-Programm den Datenstrom über eine read-Anweisung durch die Pipe und ist bereit, das zu verarbeiten, was es hat. Vergessen Sie nicht, das Rohr zu schließen, nachdem Sie den Inhalt gelesen haben. Das Listening-Programm kann auch die Ergebnisse seiner Verarbeitung über dieselbe oder eine andere Named Pipe zurückgeben. Solche programmübergreifenden Kommunikationen sind manchmal sehr bequem.

Per Anton Ronning
quelle