Thread Returncode geforkter Prozesse verabeiten
(2 answers)
Opened by robiwan at 2009-07-21 17:06
Das nachfolgende Programm zeigt wie man mit KindProzessen umgehen kann.
Wichtig sind die Zeilen: 10: da weise ich dem Signalhandler für die Kindprozesse eine Funktion zu, die immer dann ausgeführt werden soll, wenn Ein Kind sich beendet. 27: Da zeige ich wie man nicht blockierend auf das Ende von Prozessen warten kann. Setzt man eine ProzessID statt -1 ein dann überprüft er ob dieser Prozess noch Läuft (liefert 0 oder die ProzessID zurück wenn der Prozess noch läuft (je nach System), oder -1 wenn der Prozess nicht mehr läuft) 66: Da hole ich mit mittels "wait" den letzten beendetet Prozess. in $? steht sowohl der Exitwert als auch wie der Prozess beendet wurde das erste Byte ist der Exitwert, das zweite das Signal ist das Signal "0" so wurde kein Signal an den Prozess gesendet um ihn zu beenden. Ein Exitwert von 0 bedeutet "Alles gut gelaufen". Interessand ist eventuell noch Zeile 24 da zeige ich eine Möglichkeit "kill" zu verwenden. Das Signal "9" veranlasst das Betriebssystem den Prozess an den das Signal ging sofort zu beenden. Ein Signal "15" würde den Prozess selber auffordern sich zu beenden (es wird die Funktion in "$SIG{TERM}" aufgerufen defaultmäßig ist das "exit(0)") Man kann auch noch andere Signale senden, die dann vom anderen Prozess verarbeitet werden kann. In "create_child" (Zeile 35 ff.) zeige ich wie "fork" gut handhabt. Code (perl): (dl
)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 #!/usr/bin/perl use strict; use warnings; # exportiert (unter anderem) die funktion: WNOHANG use POSIX ':sys_wait_h'; # Signalhanler einrichten # Die hier gespeicherte Funktionsreferenz wird aufgerufen, # wenn ein kindprozess Kindpozess beendet wurde $SIG{CHLD}=\&on_sig_child; # drei Prozesse erzeugen for(0..2) { create_child(); sleep 1; } # ein Prozess erzeugen den wir "killen" werden: my $killpid=create_child(); sleep 1; # prozess hart beeneden: kill(9, $killpid) if($killpid); # so lange Schleifendurchlauf wie noch KindProzesse laufen; sleep 1 while(waitpid(-1,WNOHANG())!= -1); exit(); ################## ### Funktionen ######################################################### ################## # Kindprozess erzeugen sub create_child { # KindProzess erzeugen, # indem der eigenen Prozess dubliziert wird. my $pid=fork; # wenn pid definiert und != 0 # wir sind im Elternprozess if($pid) { print "CREATE CHILD($pid)\n"; } # pid definiert und 0 # wir sinb im Kindprozess elsif(defined($pid)) { $SIG{CHLD}='IGNORE'; child_working(); } # pid nicht definiert # ein Fehler ist aufgetreten else { warn "fork faild ($!)\n"; } return $pid; } # der SignalHandler sub on_sig_child { # Welcher KindProzess wurde beendet? my $pid=wait(); # Eine Meldung machen: print "EXIT CHILD: $pid\n"; # Der Wert der mit "exit" zurück geliefert wurde print " CODE: ".($?>>8)."\n"; # Wie wurde der Prozess bendet 0=ohne externes Signal; # Andere Werte siehe "man signal" print " SIGNAL: ".($?&127)."\n"; } sub child_working { # ein wenig schlafen sleep(7); # einen zufällgen Exitstatus zwishen 0 und 4 erzeugen my $exitstatus=int(rand(5)); print "Child($$) exit($exitstatus)\n"; exit($exitstatus); } |