Re: fork(), exec() und dup()

Datumsansicht Baumansicht Betreffansicht Attachement-Sicht

From: Christian Weisgerber (naddy_at_mips.inka.de)
Date: 19. Jul 2000


Wolfgang Jährling <wolfgang_at_pro-linux.de> wrote:

> Das interessiert mich jetzt näher, da ich vorhatte, mich demnächst
> auch
> mal daran zu versuchen. Wie kommt so ein Deadlock zustande? Ich habe
> zwar
> schon einige Doku zu IPC im Netz gelesen, aber dazu stand nirgends
> was.

Was mich interessiert: Was denken sich eigentlich die Leute dabei,
die Artikel mit einer Formatierung wie oben ins Netz stellen? Ja,
das ist der Originalumbruch. Da mittlerweile eine stattlicher Anteil
aller Mitteilungen, die mir in den News oder auf Mailinglisten
begegnen, derartig zerfleddert ist, muss ja etwas dahinterstehen.
Ein Fortschritt, der sich mir nicht erschließt. Ich bin geneigt
das als unlesbar zu ignorieren und ggfs. den Absender gleich im
Killfile zu entsorgen.

Zum Thema:

> Das interessiert mich jetzt näher, da ich vorhatte, mich demnächst
> auch mal daran zu versuchen. Wie kommt so ein Deadlock zustande?

Zwei Prozesse, die jeweils auf eine Eingabe vom anderen warten,
bevor sie ihm wieder eine Ausgabe schicken. Normalerweise hat man
ein verzahntes Wechselspiel:

        A schreibt --->
                       ---> B liest
                       <--- B schreibt
        A liest <---
        A schreibt --->
                       ---> B liest
                     ...

Schreibt einer der Prozesse einmal nichts, dann verklemmt sich das.
Beide schreiben erst wieder, wenn sie etwas vom anderen gelesen
haben => nichts geht mehr.

Neben Fehlern in der Programmlogik, ist in der Praxis die Stdio-
Pufferung eine Falle bei der Verwendung solcher Koprozesse. Per
Default ist die Standardausgabe auf TTY zeilenweise, sonst blockweise
gepuffert. Das »sonst« schließt auch Pipes und Socketpairs ein.

Die zeilenweise Pufferung kann man leicht demonstrieren:

$ perl -e 'print "foo"; sleep 2; print "bar\n"'

Was passiert? Wird "foo" ausgegeben, zwei Sekunden gewartet, dann
"bar"? Nein. Zwei Sekunden lang kommt nichts, dann "foobar" am
Stück. Dagegen erfolgen bei

$ perl -e 'print "foo\n"; sleep 2; print "bar\n"'

beide Ausgaben durch die Pause getrennt. Die Stdio-Bibliothek
puffert die Ausgabe und gibt sie erst mit dem Erreichen des
Zeilenendes tatsächlich aus. Ist das Ziel kein TTY, dann wird gleich
ein mehrere Kilobyte (genaue Zahl implementierungsabhängig) großer
Block gepuffert. Das ist eine feste Funktion der Stdio-Bibliothek
und kann, wenn ein Programm diese verwendet, von außerhalb des
Programms nicht beeinflusst werden.

Wer z.B. sed(1) als Filter in einem Koprozess einsetzen möchte,
eine Zeile schreibt und glaubt, dann direkt die verarbeitete Zeile
lesen zu können, wird eine Überraschung erleben.

Um die Handhabung von Koprozessen ein wenig zu erforschen, empfehle
ich die Korn-Shell (ksh). Dort kann man mit »|&« einen Koprozess
erzeugen, mit »print -p« bzw. »read -p« mit ihm kommunizieren, oder
mit »>&p« und »<&p« Standardausgabe bzw. -eingabe zu ihm umlenken.

perlipc(1) enthält auch einige Hinweise zu diesem Thema.

-- 
Christian "naddy" Weisgerber                          naddy_at_mips.inka.de


Datumsansicht Baumansicht Betreffansicht Attachement-Sicht

Dieses Archiv wurde generiert von hypermail 2.1.2 : 11. Mar 2002 CET