Perl fork (), как проверить, если ребенок потерпел крах - PullRequest
0 голосов
/ 08 ноября 2018

У меня есть некоторый Perl-код, который генерирует несколько дочерних процессов. Основной код выглядит следующим образом:

 my $forked = 0;
 my $err = 0;
 my $Processes_To_Use_After_Calc=10;     
 print "Parent ($$) has started\n";
 for my $ispawn (1 .. $Processes_To_Use_After_Calc){
    my $child_pid = fork();
    die "Cannot fork: $!" if !defined $child_pid; # system overload
    if(defined $child_pid && $child_pid > 0) {
        ## Parent
        $forked++;
    } elsif(defined $child_pid){
        #
        # Here some calculations are performed
        #
        print "Child $$ has finished (number $ispawn) \n";
    }
}
for(1..$forked) {
    my $child_pid = wait();
}

Все довольно стандартные вещи. Теперь я хотел бы знать, происходит ли сбой какого-либо из дочерних процессов (не удалось правильно завершить). Ясно, что если не будет напечатано последнее утверждение каждого дочернего процесса, я могу предположить, что возникла проблема. Однако я хотел бы другой метод, который полностью завершил бы родительскую программу и закрыл бы все дочерние процессы, которые все еще были открыты, если один из дочерних процессов завершился сбоем. Возможно ли это?

Ответы [ 2 ]

0 голосов
/ 08 ноября 2018

wait комплектов $?

В вашей системе ведет себя подобно wait(2): он ожидает завершения дочернего процесса и возвращает pid умершего процесса, или -1, если нет дочерних процессов. Статус возвращается в $? и $ {^CHILD_ERROR_NATIVE}.

Итак,

my $child_pid = wait();

if    ( $? == -1  ) { die "wait failed: $!\n"; }
elsif ( $? & 0x7F ) { warn "Child $child_pid killed by signal ".( $? & 0x7F )."\n"); }
elsif ( $? >> 8   ) { warn "Child $child_pid exited with error ".( $? >> 8 )."\n"); }
else                { print "Child $child_pid exited successfully\n"; }

Если программа действительно потерпела крах, вы получите Child killed by signal 11, то есть SIGSEGV.

Если бы он выдал необнаруженное исключение, вы, скорее всего, получите Child exited with error XXX. Точное значение зависит от программы и может быть бессмысленным. По умолчанию Perl использует $! || ($? >> 8) || 255 для значения выхода в необработанном исключении.

0 голосов
/ 08 ноября 2018

Согласно документу для wait:

ведет себя как wait (2) в вашей системе: он ожидает завершения дочернего процесса и возвращает pid умершего процесса, или "-1 "если нет дочерних процессов.Статус возвращается в $?и "$ {^ CHILD_ERROR_NATIVE}".Обратите внимание, что возвращаемое значение «-1» может означать, что дочерние процессы автоматически запускаются, как описано в perlipc.

Если ваш ребенок был убит сигналом, $? & 0x7F будет истинным иравно номеру сигнала, убившего ребенка.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...