In perl, zu töten Kind und seine Kinder, als Kind wurde erstellt mit open

Hier ist mein code, mit Fehlerbehandlung und andere Sachen entfernt, die für Klarheit:

sub launch_and_monitor {  

    my ($script, $timeout) = @_;

    sub REAPER {
        while ((my $child = waitpid(-1, &WNOHANG)) > 0) {}
        $SIG{CHLD} = \&REAPER;
    }
    $SIG{CHLD} = \&REAPER;

    my $pid = fork;
    if (defined $pid) {
        if ($pid == 0) {
            # in child
            monitor($timeout);
        }
        else {
            launch($script);
        }
    }
}

Den Start sub führt ein shell-Skript, das wiederum startet andere Prozesse, etwa so:

sub launch($) {

    my ($script) = @_;

    my $pid = open(PIPE, "$script|");

    # write pid to pidfile

    if ($pid != 0) {
        while(<PIPE>) {
            # do stuff with output
        }
        close(PIPE) or die $!;
    }
}

Den monitor sub im Grunde nur darauf wartet für eine bestimmte Zeit und dann versucht zu töten das shell-Skript.

sub monitor($) {

    my ($timeout) = @_;

    sleep $timeout;

    # check if script is still running and if so get pid from pidfile
    if (...) {
        my $pid = getpid(...);        
        kill 9, $pid;
    }
}

Dieser tötet das Skript, aber es tötet nicht, es ist sub-Prozesse. Wie zu beheben?

  • Ich habe keine Antwort auf deine Hauptfrage, aber ich würde empfehlen, machen REAPER eine anonyme sub, z.B. my $reaper = sub { ... }; $SIG{CHLD} = $reaper; Setzen eines namens sub in einem anderen sub nicht verstecken Sie von anderen Bereichen. Alle genannten subs sind package-Symbole in Perl
  • speculation.org/garrick/kill-9.html
  • guter Punkt, danke für den Hinweis
InformationsquelleAutor richard | 2009-11-04
Schreibe einen Kommentar