Thread Returncode geforkter Prozesse verabeiten (2 answers)
Opened by robiwan at 2009-07-21 17:06

topeg
 2009-07-22 04:19
#123451 #123451
User since
2006-07-10
2611 Artikel
BenutzerIn

user image
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);
}

View full thread Returncode geforkter Prozesse verabeiten