beispiel block 2 · slides by benedikt huber 1 . fork, exec, exit und wait prozess erzeugen...
TRANSCRIPT
![Page 1: Beispiel Block 2 · Slides by Benedikt Huber 1 . fork, exec, exit und wait Prozess erzeugen Programmabbild ersetzen Programm beenden Auf Ende eines Prozesses warten 2 . Prozesseigenschaften](https://reader034.vdocuments.pub/reader034/viewer/2022050116/5f4d27fa6021977ec95662ff/html5/thumbnails/1.jpg)
Beispiel Block 2 Parallele Prozesse: fork, exec und wait Interprozesskommunikation mit Unnamed Pipes
Oliver Höftberger
SS 2013
Slides by Benedikt Huber 1
![Page 2: Beispiel Block 2 · Slides by Benedikt Huber 1 . fork, exec, exit und wait Prozess erzeugen Programmabbild ersetzen Programm beenden Auf Ende eines Prozesses warten 2 . Prozesseigenschaften](https://reader034.vdocuments.pub/reader034/viewer/2022050116/5f4d27fa6021977ec95662ff/html5/thumbnails/2.jpg)
fork, exec, exit und wait
Prozess erzeugen
Programmabbild ersetzen
Programm beenden
Auf Ende eines Prozesses warten 2
![Page 3: Beispiel Block 2 · Slides by Benedikt Huber 1 . fork, exec, exit und wait Prozess erzeugen Programmabbild ersetzen Programm beenden Auf Ende eines Prozesses warten 2 . Prozesseigenschaften](https://reader034.vdocuments.pub/reader034/viewer/2022050116/5f4d27fa6021977ec95662ff/html5/thumbnails/3.jpg)
Prozesseigenschaften Linux (1)
Zustand Running, Stopped, …
Scheduling Priorität, CPU-Zeit, …
Identifikation PID, Owner, Gruppe, …
Speicherverwaltung Pointer auf MMU Info
Signale Mask, Pending
Prozessverwandschaften Parents, Siblings
4/9/2013 3
![Page 4: Beispiel Block 2 · Slides by Benedikt Huber 1 . fork, exec, exit und wait Prozess erzeugen Programmabbild ersetzen Programm beenden Auf Ende eines Prozesses warten 2 . Prozesseigenschaften](https://reader034.vdocuments.pub/reader034/viewer/2022050116/5f4d27fa6021977ec95662ff/html5/thumbnails/4.jpg)
Prozesseigenschaften Linux (2)
Process Control Block Register, PC, Statuswort, Segmentregister, Page Table Info
Kernelstack
Dateideskriptorentabelle
Berechtigungen, Accounting Information
Timerverwaltung
Interprozesskommunikation
Siehe: sched.h / struct task_struct
4/9/2013 4
![Page 5: Beispiel Block 2 · Slides by Benedikt Huber 1 . fork, exec, exit und wait Prozess erzeugen Programmabbild ersetzen Programm beenden Auf Ende eines Prozesses warten 2 . Prozesseigenschaften](https://reader034.vdocuments.pub/reader034/viewer/2022050116/5f4d27fa6021977ec95662ff/html5/thumbnails/5.jpg)
Prozesshierarchie
Jeder Prozess hat
Vaterprozess
Ausnahme: init
Jeder Prozess hat
eine eindeutige ID (pid_t)
init─┬─acpid
├─ahc_dv_0
├─ahc_dv_1
├─bash
├─clock-applet
├─crond
├─cups-config-dae
├─cupsd
├─2*[dbus-daemon-1]
├─dbus-launch
├─dhcpd
├─gdm-binary─┬─gdm-binary─┬─X
│ │ └─gdmgreeter
│ └─gdm-binary─── ...
├─2*[sendmail]
├─sesam_server─┬─sesam_server
│ └─sesam_server── ...
├─smbd───5*[smbd]
├─sshd─┬─sshd───sshd───bash───pine
│ ├─sshd───sshd───bash───pine
. .
5
![Page 6: Beispiel Block 2 · Slides by Benedikt Huber 1 . fork, exec, exit und wait Prozess erzeugen Programmabbild ersetzen Programm beenden Auf Ende eines Prozesses warten 2 . Prozesseigenschaften](https://reader034.vdocuments.pub/reader034/viewer/2022050116/5f4d27fa6021977ec95662ff/html5/thumbnails/6.jpg)
Erstellen von Prozessen
Prozesse werden üblicherweise mit fork(2)
erzeugt.
Weitere Möglichkeit: clone(2)
In der Übung ist ausschließlich fork(2) zu verwenden
exec(3) überschreibt den aktuellen Prozess durch
ein anderes Programm.
wait(3) wartet auf die Terminierung eines Kindes
6
![Page 7: Beispiel Block 2 · Slides by Benedikt Huber 1 . fork, exec, exit und wait Prozess erzeugen Programmabbild ersetzen Programm beenden Auf Ende eines Prozesses warten 2 . Prozesseigenschaften](https://reader034.vdocuments.pub/reader034/viewer/2022050116/5f4d27fa6021977ec95662ff/html5/thumbnails/7.jpg)
7
fork() / exec() / wait()
fork()
• erzeugt neuen Prozess
exec*(„program“)
• ersetzt image eines Prozesses durch neues Programm
exit(status)
• beendet Prozess
wait*(&status)
• wartet auf Beendigung des Kindprozesses
fork parent fork child
exec
wait exit
initialize
child context
![Page 8: Beispiel Block 2 · Slides by Benedikt Huber 1 . fork, exec, exit und wait Prozess erzeugen Programmabbild ersetzen Programm beenden Auf Ende eines Prozesses warten 2 . Prozesseigenschaften](https://reader034.vdocuments.pub/reader034/viewer/2022050116/5f4d27fa6021977ec95662ff/html5/thumbnails/8.jpg)
8
fork()
Erzeugt einen neuen Prozess
Neuer Prozess ist eine identische Kopie des aufrufenden Prozesses (bis auf PID, Locks, ...)
Erzeugender Prozess ist Vater des erzeugten Prozesses
Beide Prozesse laufen parallel und führen dasselbe Programm aus
fork parent fork child
exec
wait exit
initialize
child context
![Page 9: Beispiel Block 2 · Slides by Benedikt Huber 1 . fork, exec, exit und wait Prozess erzeugen Programmabbild ersetzen Programm beenden Auf Ende eines Prozesses warten 2 . Prozesseigenschaften](https://reader034.vdocuments.pub/reader034/viewer/2022050116/5f4d27fa6021977ec95662ff/html5/thumbnails/9.jpg)
9
fork()
nPID = fork()
Vaterprozess
PC
nPID = fork()
Vaterprozess
PCnPID = fork()
Kindprozess
PC
Vor dem fork
Nach dem fork
![Page 10: Beispiel Block 2 · Slides by Benedikt Huber 1 . fork, exec, exit und wait Prozess erzeugen Programmabbild ersetzen Programm beenden Auf Ende eines Prozesses warten 2 . Prozesseigenschaften](https://reader034.vdocuments.pub/reader034/viewer/2022050116/5f4d27fa6021977ec95662ff/html5/thumbnails/10.jpg)
10
fork()
Unterscheidung zwischen Vater- und Kindprozess durch den Rückgabewert von fork(): • -1 im Fehlerfall
• 0 im Kindprozess (child)
• >0 im aufrufenden Prozess (parent)
![Page 11: Beispiel Block 2 · Slides by Benedikt Huber 1 . fork, exec, exit und wait Prozess erzeugen Programmabbild ersetzen Programm beenden Auf Ende eines Prozesses warten 2 . Prozesseigenschaften](https://reader034.vdocuments.pub/reader034/viewer/2022050116/5f4d27fa6021977ec95662ff/html5/thumbnails/11.jpg)
11
fork()
Kindprozess erbt von Elternprozess offene Dateien (gemeinsamer Zugriff!)
Dateipuffer
Signaldefinitionen
momentane Variablenwerte
Jedoch gilt: Variablen sind lokal (keine Beeinflussung)
Signale können lokal umgesetzt werden
Kommunikation (IPC) via Pipes, Sockets, Shared Memory, ...
![Page 12: Beispiel Block 2 · Slides by Benedikt Huber 1 . fork, exec, exit und wait Prozess erzeugen Programmabbild ersetzen Programm beenden Auf Ende eines Prozesses warten 2 . Prozesseigenschaften](https://reader034.vdocuments.pub/reader034/viewer/2022050116/5f4d27fa6021977ec95662ff/html5/thumbnails/12.jpg)
12
C-Interface
#include <sys/types.h>
#include <unistd.h>
pid_t fork(void);
![Page 13: Beispiel Block 2 · Slides by Benedikt Huber 1 . fork, exec, exit und wait Prozess erzeugen Programmabbild ersetzen Programm beenden Auf Ende eines Prozesses warten 2 . Prozesseigenschaften](https://reader034.vdocuments.pub/reader034/viewer/2022050116/5f4d27fa6021977ec95662ff/html5/thumbnails/13.jpg)
13
Verwendung von fork()
pid_t pid; ... switch (pid= fork()) { case -1: bail_out( “can‘t fork“ ); break; case 0: /* child: ChildProcess() */ ... exit(EXIT_SUCCESS); break; default: /* parent: ParentProcess() */ ... break; }
![Page 14: Beispiel Block 2 · Slides by Benedikt Huber 1 . fork, exec, exit und wait Prozess erzeugen Programmabbild ersetzen Programm beenden Auf Ende eines Prozesses warten 2 . Prozesseigenschaften](https://reader034.vdocuments.pub/reader034/viewer/2022050116/5f4d27fa6021977ec95662ff/html5/thumbnails/14.jpg)
clone(2), vfork(2)
clone() wird von fork(2), vfork(2) aufgerufen. clone() erlaubt Kontrolle über die zu duplizierenden
Eigenschaften (Linux spezifisch, nicht portabel!)
vfork(): blockiert bis exec(), das Kind darf keine Variablen mehr ändern, und nur noch exec() ausführen. Veraltet, nicht mehr empfohlen
clone(), vfork() ist kein Teil des Stoffes!
14
![Page 15: Beispiel Block 2 · Slides by Benedikt Huber 1 . fork, exec, exit und wait Prozess erzeugen Programmabbild ersetzen Programm beenden Auf Ende eines Prozesses warten 2 . Prozesseigenschaften](https://reader034.vdocuments.pub/reader034/viewer/2022050116/5f4d27fa6021977ec95662ff/html5/thumbnails/15.jpg)
15
exec()
Erlaubt es einem Prozess, ein anderes Programm auszuführen
Startet ein neues Programm innerhalb eines Prozesses
PID bleibt gleich
fork parent fork child
exec
wait exit
initialize
child context
![Page 16: Beispiel Block 2 · Slides by Benedikt Huber 1 . fork, exec, exit und wait Prozess erzeugen Programmabbild ersetzen Programm beenden Auf Ende eines Prozesses warten 2 . Prozesseigenschaften](https://reader034.vdocuments.pub/reader034/viewer/2022050116/5f4d27fa6021977ec95662ff/html5/thumbnails/16.jpg)
Die exec() Familie (1)
int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execle(const char *path, const char *arg, ... , char * const envp[]);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int fexecve(int fd, char *const argv[], char *const envp[]);
16
![Page 17: Beispiel Block 2 · Slides by Benedikt Huber 1 . fork, exec, exit und wait Prozess erzeugen Programmabbild ersetzen Programm beenden Auf Ende eines Prozesses warten 2 . Prozesseigenschaften](https://reader034.vdocuments.pub/reader034/viewer/2022050116/5f4d27fa6021977ec95662ff/html5/thumbnails/17.jpg)
17
Die exec() Familie (2)
Ersetzt aktuelles Programm durch das in der Datei path enthaltene
exec*p - Variante sucht (wie Shell) in $PATH nach Programm mit dem spezifierten Namen
Argumentübergabe beachten! – Argumentliste muss mit NULL Zeiger enden
Varianten mit variable Argumentanzahl (execl*) und Argumentarray (execv*)
Variante execle: Environment kann verändert werden Variante fexecve: akzeptiert Dateideskriptor
![Page 18: Beispiel Block 2 · Slides by Benedikt Huber 1 . fork, exec, exit und wait Prozess erzeugen Programmabbild ersetzen Programm beenden Auf Ende eines Prozesses warten 2 . Prozesseigenschaften](https://reader034.vdocuments.pub/reader034/viewer/2022050116/5f4d27fa6021977ec95662ff/html5/thumbnails/18.jpg)
18
execv(), execvp()
#include <unistd.h>
int execv(char *path, char *argv[] ); int execvp(char *filename, char *argv[] ); char *cmd[] = { "ls", "-l", (char *) 0 }; (void) execv ("/bin/ls", cmd); (void) execvp ("ls", cmd); bail_out ( “can‘t exec“ );
![Page 19: Beispiel Block 2 · Slides by Benedikt Huber 1 . fork, exec, exit und wait Prozess erzeugen Programmabbild ersetzen Programm beenden Auf Ende eines Prozesses warten 2 . Prozesseigenschaften](https://reader034.vdocuments.pub/reader034/viewer/2022050116/5f4d27fa6021977ec95662ff/html5/thumbnails/19.jpg)
19
execl(), execlp()
#include <unistd.h> int execl(char *path, char *arg0, ..., char *arg_n,(char*)0); int execlp(char *filename, char *arg0, ..., char *arg_n, (char*)0); (void) execl ( “/bin/ls“, “ls“, “-l“, (char*) 0 ); (void) execlp ( “ls“, “ls“, “-l“, (char*) 0 ); bail_out ( “can‘t exec“ );
![Page 20: Beispiel Block 2 · Slides by Benedikt Huber 1 . fork, exec, exit und wait Prozess erzeugen Programmabbild ersetzen Programm beenden Auf Ende eines Prozesses warten 2 . Prozesseigenschaften](https://reader034.vdocuments.pub/reader034/viewer/2022050116/5f4d27fa6021977ec95662ff/html5/thumbnails/20.jpg)
20
exit()
Beendet den aktuellen Prozess
Rückgabewert kann von Vaterprozess abgefragt werden
Beim Beenden: • Leeren der stdio – Buffer
• Schließen offener Dateien
• Löschen von temporären Dateien (tmpfile(3))
• Aufrufen von Exit-Handlern (atexit(3))
fork parent fork child
exec
wait exit
initialize
child context
![Page 21: Beispiel Block 2 · Slides by Benedikt Huber 1 . fork, exec, exit und wait Prozess erzeugen Programmabbild ersetzen Programm beenden Auf Ende eines Prozesses warten 2 . Prozesseigenschaften](https://reader034.vdocuments.pub/reader034/viewer/2022050116/5f4d27fa6021977ec95662ff/html5/thumbnails/21.jpg)
21
exit()
void exit(int status);
Status: 8-bit (0-255)
Im C-Standard definierte Rückgabewerte • exit(EXIT_SUCCESS) keine Fehler
• exit(EXIT_FAILURE) Fehler aufgetreten
Weitere Rückgabewerte BSD: sysexits.h
http://tldp.org/LDP/abs/html/exitcodes.html
![Page 22: Beispiel Block 2 · Slides by Benedikt Huber 1 . fork, exec, exit und wait Prozess erzeugen Programmabbild ersetzen Programm beenden Auf Ende eines Prozesses warten 2 . Prozesseigenschaften](https://reader034.vdocuments.pub/reader034/viewer/2022050116/5f4d27fa6021977ec95662ff/html5/thumbnails/22.jpg)
22
wait()
Wartet bis Kindprozess terminiert
Liefert PID und Status des beendeten Prozesses
Wenn kein Kindprozess existiert, -1 als Rückgabewert (auch bei EINTR)
fork parent fork child
exec
wait exit
initialize
child context
![Page 23: Beispiel Block 2 · Slides by Benedikt Huber 1 . fork, exec, exit und wait Prozess erzeugen Programmabbild ersetzen Programm beenden Auf Ende eines Prozesses warten 2 . Prozesseigenschaften](https://reader034.vdocuments.pub/reader034/viewer/2022050116/5f4d27fa6021977ec95662ff/html5/thumbnails/23.jpg)
23
wait()
Liefert PID und Status des terminierten Kindprozesses • pid = wait(&status)
Status beinhaltet Rückgabewert und Signalinformation
WIFEXITED(status), WEXITSTATUS(status)
WIFSIGNALED(status), WTERMSIG(status)
See man 2 wait
Nach dem Aufruf von wait wird der Kindprozess aus der Prozesstabelle entfernt
![Page 24: Beispiel Block 2 · Slides by Benedikt Huber 1 . fork, exec, exit und wait Prozess erzeugen Programmabbild ersetzen Programm beenden Auf Ende eines Prozesses warten 2 . Prozesseigenschaften](https://reader034.vdocuments.pub/reader034/viewer/2022050116/5f4d27fa6021977ec95662ff/html5/thumbnails/24.jpg)
24
exit(): Zombies
UNIX: Auch bereits terminierte Prozesse besetzen einen Eintrag in der Prozesstabelle falls kein Platz mehr frei ist, kann kein neuer Prozess mehr gestartet
werden
Der Kindprozess terminiert und der Vaterprozess hat noch nicht wait ausgeführt Der Kindprozess wird auf Zustand „Zombie“ gesetzt
Eintrag in der Prozesstabelle bleibt erhalten bis der Vaterprozess wait ausführt
![Page 25: Beispiel Block 2 · Slides by Benedikt Huber 1 . fork, exec, exit und wait Prozess erzeugen Programmabbild ersetzen Programm beenden Auf Ende eines Prozesses warten 2 . Prozesseigenschaften](https://reader034.vdocuments.pub/reader034/viewer/2022050116/5f4d27fa6021977ec95662ff/html5/thumbnails/25.jpg)
25
exit(): Zombies
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {
unsigned i = 0;
while(++i) {
pid_t pid = fork();
if(pid < 0) { bail_out(“fork()”); }
if(pid == 0) { exit(EXIT_SUCCESS); }
printf(“We now have %d zombies…\n",i);
}
}
![Page 26: Beispiel Block 2 · Slides by Benedikt Huber 1 . fork, exec, exit und wait Prozess erzeugen Programmabbild ersetzen Programm beenden Auf Ende eines Prozesses warten 2 . Prozesseigenschaften](https://reader034.vdocuments.pub/reader034/viewer/2022050116/5f4d27fa6021977ec95662ff/html5/thumbnails/26.jpg)
26
exit(): Orphans
UNIX: Auch bereits terminierte Prozesse besetzen einen Eintrag in der Prozesstabelle falls kein Platz mehr frei ist, kann kein neuer Prozess mehr gestartet
werden
Der Vaterprozess terminiert und der Kindprozess wurde noch nicht beendet Kind Prozess „verwaist“ (orphan) und wird dem init Prozess vererbt
Nach der Beendigung eines Orphans entfernt init den Prozesseintrag
![Page 27: Beispiel Block 2 · Slides by Benedikt Huber 1 . fork, exec, exit und wait Prozess erzeugen Programmabbild ersetzen Programm beenden Auf Ende eines Prozesses warten 2 . Prozesseigenschaften](https://reader034.vdocuments.pub/reader034/viewer/2022050116/5f4d27fa6021977ec95662ff/html5/thumbnails/27.jpg)
27
C-Interface
#include <sys/wait.h> pid_t wait ( int * status );
int status; pid_t child_pid, pid; ...
while ((pid = wait(&status)) != child_pid ) {
bail_out( “can‘t wait“, 1 ); } if (WEXITSTATUS(status) == EXIT_SUCCESS ) ...
Stoppt Prozessausführung
bis entweder Kindprozess
terminiert oder ein Fehler
auftritt (≠ busy waiting).
if (pid != -1) continue; /* other child */
if (errno == EINTR) continue; /* interrupted */
![Page 28: Beispiel Block 2 · Slides by Benedikt Huber 1 . fork, exec, exit und wait Prozess erzeugen Programmabbild ersetzen Programm beenden Auf Ende eines Prozesses warten 2 . Prozesseigenschaften](https://reader034.vdocuments.pub/reader034/viewer/2022050116/5f4d27fa6021977ec95662ff/html5/thumbnails/28.jpg)
28
waitpid(): verwandter Call to wait()
Warten auf das Terminieren eines Prozesses mit einer bestimmten Prozess ID:
pid_t waitpid (pid_t pid,
int *status,
int options);
waitpid(-1,&status,0) äquivalent zu wait
waitpid(pid, &status, 0) wartet auf Kind mit PID pid
waitpid(-1, &status, WNOHANG) blockiert nicht.
![Page 29: Beispiel Block 2 · Slides by Benedikt Huber 1 . fork, exec, exit und wait Prozess erzeugen Programmabbild ersetzen Programm beenden Auf Ende eines Prozesses warten 2 . Prozesseigenschaften](https://reader034.vdocuments.pub/reader034/viewer/2022050116/5f4d27fa6021977ec95662ff/html5/thumbnails/29.jpg)
Wurde ein Kind beendet?
Synchron waitpid(-1,&status, WNOHANG)
Blockiert nicht, holt Exit-Status falls ein Kind beendet
wurde (Polling)
Asynchron
Wenn ein Kind beendet wurde wird das Signal SIGCHLD
an den Elternprozess gesendet.
Installieren eines Signalhandlers (sigaction) für
SIGCHLD
Aufruf von wait im Signal Handler
29
![Page 30: Beispiel Block 2 · Slides by Benedikt Huber 1 . fork, exec, exit und wait Prozess erzeugen Programmabbild ersetzen Programm beenden Auf Ende eines Prozesses warten 2 . Prozesseigenschaften](https://reader034.vdocuments.pub/reader034/viewer/2022050116/5f4d27fa6021977ec95662ff/html5/thumbnails/30.jpg)
30
Rückblende Teil 1
fork() - Kindprozess erzeugen
exec() - neues Programm innerhalb eines Prozesses
starten
exit() – den aktuellen Prozess beenden
wait() - im Vaterprozess auf die Terminierung des
Kindprozesses warten
![Page 31: Beispiel Block 2 · Slides by Benedikt Huber 1 . fork, exec, exit und wait Prozess erzeugen Programmabbild ersetzen Programm beenden Auf Ende eines Prozesses warten 2 . Prozesseigenschaften](https://reader034.vdocuments.pub/reader034/viewer/2022050116/5f4d27fa6021977ec95662ff/html5/thumbnails/31.jpg)
Fallstricke
int main(…)
{
fprintf(stdout,“Hallo“);
fork();
return 0;
}
Ausgabe: “HalloHallo“
Warum?
31
![Page 32: Beispiel Block 2 · Slides by Benedikt Huber 1 . fork, exec, exit und wait Prozess erzeugen Programmabbild ersetzen Programm beenden Auf Ende eines Prozesses warten 2 . Prozesseigenschaften](https://reader034.vdocuments.pub/reader034/viewer/2022050116/5f4d27fa6021977ec95662ff/html5/thumbnails/32.jpg)
Fallstricke
int main(…)
{
fprintf(stdout,“Hallo“);
fork();
return 0;
}
Ausgabe: “HalloHallo“
Warum?
32
Stream IO
„Hallo“
IO
OS
Stream IO
„Hallo“
IO
OS
Stream IO
„Hallo“
IO
fork
![Page 33: Beispiel Block 2 · Slides by Benedikt Huber 1 . fork, exec, exit und wait Prozess erzeugen Programmabbild ersetzen Programm beenden Auf Ende eines Prozesses warten 2 . Prozesseigenschaften](https://reader034.vdocuments.pub/reader034/viewer/2022050116/5f4d27fa6021977ec95662ff/html5/thumbnails/33.jpg)
Fallstricke
int main(…)
{
fprintf(stdout,“Hallo“);
fflush(stdout);
fork();
return 0;
}
Ausgabe: “Hallo“
33
Stream IO
„Hallo“
IO
OS
Stream IO
„Hallo“
IO
OS
Stream IO
„Hallo“
IO
fork
Stream IO
<empty>
IO
OS
Stream IO
<empty>
IO
OS
Stream IO
<empty>
IO
fork
![Page 34: Beispiel Block 2 · Slides by Benedikt Huber 1 . fork, exec, exit und wait Prozess erzeugen Programmabbild ersetzen Programm beenden Auf Ende eines Prozesses warten 2 . Prozesseigenschaften](https://reader034.vdocuments.pub/reader034/viewer/2022050116/5f4d27fa6021977ec95662ff/html5/thumbnails/34.jpg)
Unnamed Pipes
pipe() und dup()
34
![Page 35: Beispiel Block 2 · Slides by Benedikt Huber 1 . fork, exec, exit und wait Prozess erzeugen Programmabbild ersetzen Programm beenden Auf Ende eines Prozesses warten 2 . Prozesseigenschaften](https://reader034.vdocuments.pub/reader034/viewer/2022050116/5f4d27fa6021977ec95662ff/html5/thumbnails/35.jpg)
35
Pipes
Kommunikationskanal zwischen verwandten
Prozessen
Eigenschaften:
Unidirektional (2 Pipes für Übertragung in beide
Richtungen)
„Stream“ von Daten
Implizite Synchronisation
![Page 36: Beispiel Block 2 · Slides by Benedikt Huber 1 . fork, exec, exit und wait Prozess erzeugen Programmabbild ersetzen Programm beenden Auf Ende eines Prozesses warten 2 . Prozesseigenschaften](https://reader034.vdocuments.pub/reader034/viewer/2022050116/5f4d27fa6021977ec95662ff/html5/thumbnails/36.jpg)
36
Verwendung von Pipes (1)
Pipe wird mittels eines Feldes von zwei Integer-
Elementen deklariert
int fildes[2];
Deskriptor fildes[0] ist Leseende
Deskriptor fildes[1] ist Schreibende
Nicht verwendete Enden müssen geschlossen
werden
Schreibender Prozess schließt das Leseende
Lesender Prozess schließt das Schreibende
![Page 37: Beispiel Block 2 · Slides by Benedikt Huber 1 . fork, exec, exit und wait Prozess erzeugen Programmabbild ersetzen Programm beenden Auf Ende eines Prozesses warten 2 . Prozesseigenschaften](https://reader034.vdocuments.pub/reader034/viewer/2022050116/5f4d27fa6021977ec95662ff/html5/thumbnails/37.jpg)
37
Verwendung von Pipes (1)
write()
Prozess
read()
p[1]→
p[0]←
write()
Kindprozess
read()
p[1]→
p[0]←
write()
Vaterprozess
read()p[0]→
p[1]←
←←
ohne geschlossene Enden
![Page 38: Beispiel Block 2 · Slides by Benedikt Huber 1 . fork, exec, exit und wait Prozess erzeugen Programmabbild ersetzen Programm beenden Auf Ende eines Prozesses warten 2 . Prozesseigenschaften](https://reader034.vdocuments.pub/reader034/viewer/2022050116/5f4d27fa6021977ec95662ff/html5/thumbnails/38.jpg)
38
Verwendung von Pipes (1)
geschlossene Enden
write()
Kindprozess
read()
p[1]→ write()
Vaterprozess
read()p[0]→
←←
![Page 39: Beispiel Block 2 · Slides by Benedikt Huber 1 . fork, exec, exit und wait Prozess erzeugen Programmabbild ersetzen Programm beenden Auf Ende eines Prozesses warten 2 . Prozesseigenschaften](https://reader034.vdocuments.pub/reader034/viewer/2022050116/5f4d27fa6021977ec95662ff/html5/thumbnails/39.jpg)
39
Verwendung von Pipes (2)
Öffnen einer Pipe mittels Systemaufruf pipe()
fdopen() erstellt einen mit dem gegebenen Filedeskriptor assozierten Stream (FILE *)
Verwendung von Funktionen, die auf Streams operieren
z.B. fopen(), fclose()
dup2() kann zum Umlenken von Dateien verwendet werden
![Page 40: Beispiel Block 2 · Slides by Benedikt Huber 1 . fork, exec, exit und wait Prozess erzeugen Programmabbild ersetzen Programm beenden Auf Ende eines Prozesses warten 2 . Prozesseigenschaften](https://reader034.vdocuments.pub/reader034/viewer/2022050116/5f4d27fa6021977ec95662ff/html5/thumbnails/40.jpg)
40
C-Interface
#include <limits.h> /* for PIPE_BUF */
#include <unistd.h> /* prototype */
int fildes[2];
if (pipe(fildes) != 0)
{
bail_out( “can‘t create pipe“, 1 );
}
![Page 41: Beispiel Block 2 · Slides by Benedikt Huber 1 . fork, exec, exit und wait Prozess erzeugen Programmabbild ersetzen Programm beenden Auf Ende eines Prozesses warten 2 . Prozesseigenschaften](https://reader034.vdocuments.pub/reader034/viewer/2022050116/5f4d27fa6021977ec95662ff/html5/thumbnails/41.jpg)
dup(2), dup2(2)
dup() dupliziert einen File-Deskriptor.
Der neue Deskriptor erhält die niedrigste nicht
verwendete ID
Duplizierter Deskriptor zeigt auf dieselbe „open file
description“ (file offset, file status flags) man 2 open
dup2(old, new) Schließt Filedeskriptor mit ID new
Dupliziert old, der neue Deskriptor erhält ID new
41
![Page 42: Beispiel Block 2 · Slides by Benedikt Huber 1 . fork, exec, exit und wait Prozess erzeugen Programmabbild ersetzen Programm beenden Auf Ende eines Prozesses warten 2 . Prozesseigenschaften](https://reader034.vdocuments.pub/reader034/viewer/2022050116/5f4d27fa6021977ec95662ff/html5/thumbnails/42.jpg)
Umleiten der Standardein-/ausgabe
Anwendung: Kommunikation mit
Kommandozeilen-Utility, welches über
Standardeingabe / Standardausgabe kommuniziert
Strategie: Umleiten der Standardeingabe (0) oder
Standardausgabe (1) in neuem Prozess
Schließen des Filedeskriptors (z.B. fileno(stdin)) für
Standard I/O
Duplizieren eines offenen FDs (z.B. file_descr[0]) auf
eben geschlossenen (fileno(stdin))
Schließen des duplizierten FDs (file_descr[0])
42
![Page 43: Beispiel Block 2 · Slides by Benedikt Huber 1 . fork, exec, exit und wait Prozess erzeugen Programmabbild ersetzen Programm beenden Auf Ende eines Prozesses warten 2 . Prozesseigenschaften](https://reader034.vdocuments.pub/reader034/viewer/2022050116/5f4d27fa6021977ec95662ff/html5/thumbnails/43.jpg)
43
C-Interface #include <fcntl.h> #include <sys/types.h> #include <unistd.h> int fd; fd = open(„log.txt“,O_WRONLY|O_CREAT); dup2(fd, /* old descriptor */ fileno(stdout)); /* new descriptor */ close(fd); /* close old desc. */ (void) execlp(“grep“, “grep“, „max“, (char *) 0);
![Page 44: Beispiel Block 2 · Slides by Benedikt Huber 1 . fork, exec, exit und wait Prozess erzeugen Programmabbild ersetzen Programm beenden Auf Ende eines Prozesses warten 2 . Prozesseigenschaften](https://reader034.vdocuments.pub/reader034/viewer/2022050116/5f4d27fa6021977ec95662ff/html5/thumbnails/44.jpg)
44
Synchronisation
Lesen von leerer Pipe ist blockierend
Schreiben auf volle Pipe ebenso
Achtung: Blockiert wenn vergessen Pipe zu schließen
Lesen von Pipe ohne offene Schreibenden liefert
EOF
Schreiben auf Pipe ohne offene Leseenden liefert
SIGPIPE Signal
![Page 45: Beispiel Block 2 · Slides by Benedikt Huber 1 . fork, exec, exit und wait Prozess erzeugen Programmabbild ersetzen Programm beenden Auf Ende eines Prozesses warten 2 . Prozesseigenschaften](https://reader034.vdocuments.pub/reader034/viewer/2022050116/5f4d27fa6021977ec95662ff/html5/thumbnails/45.jpg)
45
Pipes: Pitfalls
Pipes eignen sich gut für unidirektionale
Kommunikation
Bidirektional: Zwei Pipes
Fehleranfällige Synchronisation (deadlock)
Synchronisation & Puffer
fflush() verwenden
Puffer konfigurieren (setbuf(3), setvbuf(3))
![Page 46: Beispiel Block 2 · Slides by Benedikt Huber 1 . fork, exec, exit und wait Prozess erzeugen Programmabbild ersetzen Programm beenden Auf Ende eines Prozesses warten 2 . Prozesseigenschaften](https://reader034.vdocuments.pub/reader034/viewer/2022050116/5f4d27fa6021977ec95662ff/html5/thumbnails/46.jpg)
46
Rückblende
Kommunikation zwischen verwandten Prozessen
mittels Pipes.
Implizite Synchronisation
Nicht verwendete Enden schließen
Filestream für Filedeskriptor der Pipe mittels
fdopen()
Umlenken von Pipes mittels dup2()