Pipe: Unterschied zwischen den Versionen
Singh (Diskussion | Beiträge) |
Singh (Diskussion | Beiträge) |
||
Zeile 6: | Zeile 6: | ||
[[Bild:Pipes01.jpg]] | [[Bild:Pipes01.jpg]] | ||
− | In diesem Beispiel liest zuerst ein Prozess den Inhalt der Textdatei ''„winboard.txt“'' und leitet es dem Prozess bzw. Programm | + | In diesem Beispiel liest zuerst ein Prozess den Inhalt der Textdatei ''„winboard.txt“'' und leitet es dem Prozess bzw. Programm ''„grep“'' weiter. Dieser wiederrum filtert dann das Wort ''„WBWiki“'' heraus und gibt es am Bildschirm aus. Diese zwei Anweisungen werden durch das Pipe-Symbol ''"|"'' verbunden. |
Man kann also sagen, dass die Ausgabe eines Prozesses als Eingabe eines anderen Prozesses dient. | Man kann also sagen, dass die Ausgabe eines Prozesses als Eingabe eines anderen Prozesses dient. | ||
Aktuelle Version vom 11. Mai 2008, 21:18 Uhr
Pipes (engl. Rohre) sind einer der ältesten Werkzeuge in Unix um eine Kommunikationsverbindung zwischen zwei Prozessen aufzubauen. Aber heutzutage sind Pipes in fast allen modernen Betriebssystemen wiederzufinden. In Windows zum Beispiel werden Pipes durch die Windows-API realisiert. Pipes basieren auf das FIFO-Prinzip und man kann es so vorstellen, dass man zwischen zwei Prozessen ein Rohr legt und die miteinander verbindet. Damit eine reibungslose Kommunikation zwischen den zwei Prozessen gewährleistet werden kann, werden vorher zwei Dateihandels angelegt. Einer der Prozesse hat nur Lese-Rechte und das andere nur Schreib-Rechte. Diese Dateihandels müssen selbstverständlich von dem Programmierer erst festgelegt werden.
Ein beliebtes Beispiel um dieses Verfahren zu veranschaulichen ist in Unix das herausfiltern von Wörtern in einem Text-Dokument:
In diesem Beispiel liest zuerst ein Prozess den Inhalt der Textdatei „winboard.txt“ und leitet es dem Prozess bzw. Programm „grep“ weiter. Dieser wiederrum filtert dann das Wort „WBWiki“ heraus und gibt es am Bildschirm aus. Diese zwei Anweisungen werden durch das Pipe-Symbol "|" verbunden. Man kann also sagen, dass die Ausgabe eines Prozesses als Eingabe eines anderen Prozesses dient.
Programmieren einer Unix-Pipe
Wie die Implementierung einer Pipe in Unix aussieht, zeigt uns der folgende Code. Dieser Programmiercode bewirkt das gleiche wie diese Shellanweisung cat | grep
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/wait.h> int main(void){ // pipe[0] zum Lesen und pipe[1] zum Schreiben int pipe_verbindung[2]; //Initialisierung durch die Funktion Pipe pipe(pipe_verbindung); //Kindprozess erzeugen if (fork()==0){ // dup2 verbindet den Filedeskriptor der Pipe mit der Filedeskriptor der Standardausgabe dup2(pipe_verbindung[1],1); // der Leseausgang muss geschlossen werden, da dieser Prozess nichts liest close(pipe_verbindung[0]); // Kommando ausführen, Standardausgabe des Kommandos ist mit der Pipe verbunden execlp("cat","cat",0); } // dann zweiten Kindprozess erzeugen else if (fork()==0){ dup2(pipe_verbindung[0],0); close(pipe_verbindung[1]); execlp("grepp","grepp",0); } }
In diesem Programmierbeispiel wird eine Verbindung zwischen zwei Kindprozessen erstellt. Der eine Kindprozess besitzt Lese-Rechte. Der andere Schreibrechte. Zuerst wird ein eindimensionaler Array deklariert. Danach wird eine Pipe durch die Funktion pipe()
erstellt. Durch den Befehl fork()
werden anschließend dann die zwei Kindprozesse erstellt. Jetzt muss man noch durch den Befehl dup()
die Dateihandles festlegen und zusätzlich durch die Funktion close()
den anderen Filedeskriptor sperren. Das Sperren des anderen Filedeskriptor wird darum eingesetzt um Konflikte zwischen den Prozessen zu vermeiden.