Thread Skript nach Programmaufruf fortsetzen (12 answers)
Opened by IceRage at 2008-09-16 02:13

murphy
 2008-09-16 11:25
#114695 #114695
User since
2004-07-19
1776 Artikel
HausmeisterIn
[Homepage]
user image
IceRage+2008-09-16 09:00:41--
murphy+2008-09-16 00:55:26--
@IceRage: Wenn man explizit wait aufruft, darf man sich nicht wundern, dass der Elternprozess auf seine Kinder wartet, bevor er weiter läuft.

Also ich habe das wait() jetzt mal rausgenommen, der Eltern Prozess läuft aber leider dennoch nicht an. Erst wenn dich das aufgerufene Programm beendet habe.
[...]


Vor dem Eintritt Deines Elternprozesses in die Endlosschleife liest Du aus einer Pipe Daten mittels
Code (perl): (dl )
my @line = <READER>;

ein. Da du hier readline im Arraykontext verwendest, werden solange weitere Zeilen aus der Pipe gelesen, bis das Dateiende erreicht ist – das ist bei einer Pipe aber erst dann der Fall, wenn ihr anderes Ende geschlossen wurde, was Dein Kindprozess niemals tut. Die Pipe wird also erst implizit vom Systemkern geschlossen, wenn der Kindprozess stirbt und erst zu diesem Zeitpunkt wird der readline-Aufruf im Elternprozess zurückkehren.

Quote
[...]
Mir ist noch etwas Anderes aufgefallen. Wenn ich mir mal den Rückgabewert vom READER anschaue, also die PID die bei:

Code (perl): (dl )
my @line = <READER>;


ausgelesen wird, dann ist der immer exakt um den Betrag 2 zu gering, im Vergleich zu einer Ausgabe mit ps -aux | grep firefox.
[...]


Logisch, was Du da in die Pipe schreibst ist ja auch nicht die Prozessid von Firefox, sondern die von Deinem Kindprozess. So wie Dein Programm strukturiert ist, wird hier aber dreimal geforkt:

(1) Dein Programm forkt explizit.
(2) Perl forkt implizit in der Funktion system, um die Shell zu starten, ohne sich selbst zu beenden.
(3) Die Shell forkt implizit, um Firefox zu starten, ohne sich selbst zu beenden.

In vielen Systemen wird die Prozessid neuer Prozesse bei jedem Fork einfach durch das Erhöhen eines globalen Zählers generiert, was Du hier beobachtest.

Manche Systeme generieren aus Sicherheitsgründen völlig zufällige Prozessids. Irgendwelche Arithmetik mit Prozessids durchzuführen ist also unportabel und gefährlich.

Abgesehen davon müsstest Du eigentlich die Prozessid Deines Kindes nicht so schrecklich kompliziert ermitteln, sondern lediglich den Rückgabewert von fork benutzen, den Du ja sowieso speicherst...
When C++ is your hammer, every problem looks like your thumb.

View full thread Skript nach Programmaufruf fortsetzen