У меня есть сценарий Perl (фрагмент ниже), который запускается в cron для выполнения системных проверок. Я разделяю дочерний элемент как тайм-аут и получаю его с помощью SIG {CHLD}. Perl выполняет несколько системных вызовов сценариев Bash и проверяет их статус выхода. Один сценарий bash дает сбой примерно в 5% случаев без ошибок. Скрипты Bash существуют с 0, а Perl видит $? как -1 и $! как «Нет дочерних процессов».
Этот сценарий bash проверяет лицензии компилятора, а Intel icc остается после завершения сценария Bash (вывод ps ниже). Я думаю, что зомби icc завершает работу, заставляя Perl использовать обработчик SIG {CHLD}, который сдувает $? статус, прежде чем я смогу его прочитать.
Compile status -1; No child processes
#!/usr/bin/perl
use strict;
use POSIX ':sys_wait_h';
my $GLOBAL_TIMEOUT = 1200;
### Timer to notify if this program hangs
my $timer_pid;
$SIG{CHLD} = sub {
local ($!, $?);
while((my $pid = waitpid(-1, WNOHANG)) > 0)
{
if($pid == $timer_pid)
{
die "Timeout\n";
}
}
};
die "Unable to fork\n" unless(defined($timer_pid = fork));
if($timer_pid == 0) # child
{
sleep($GLOBAL_TIMEOUT);
exit;
}
### End Timer
### Compile test
my @compile = `./compile_test.sh 2>&1`;
my $status = $?;
print "Compile status $status; $!\n";
if($status != 0)
{
print "@compile\n";
}
END # Timer cleanup
{
if($timer_pid != 0)
{
$SIG{CHLD} = 'IGNORE';
kill(15, $timer_pid);
}
}
exit(0);
#!/bin/sh
cc compile_test.c
if [ $? -ne 0 ]; then
echo "Cray compiler failure"
exit 1
fi
module swap PrgEnv-cray PrgEnv-intel
cc compile_test.c
if [ $? -ne 0 ]; then
echo "Intel compiler failure"
exit 1
fi
wait
ps
exit 0
Ожидание на самом деле не ждет, потому что cc вызывает icc, который создает внук-процесс зомби, который wait (или wait PID) не блокируется. (ожидание `pidof icc`, 31589 в данном случае дает" не дочерний элемент этой оболочки ")
user 31589 1 0 12:47 pts/15 00:00:00 icc
Я просто не знаю, как это исправить в Bash или Perl.
Спасибо Крис
alarm
. Есть ли причина не использовать здесьalarm
? - person mob   schedule 05.06.2019waitpid
, выполняемый обратными кавычками, завершается ошибкой (поскольку дочерний элемент уже был получен). - person ikegami   schedule 06.06.2019bash
вызовов в реальном Perl-скрипте. Только этот периодически выходит из строя. Только что сегодня заметил, что ICC осталась позади, и ждать не могу. - person Chris   schedule 06.06.2019icc
остается (что неудобно), или это настоящая ошибка? Обратите внимание, что Статус компиляции -1; Отсутствие дочерних процессов не является ошибкой, так как у вас естьCHLD
обработчик и проверка$?
после обратных кавычек, которые, возможно, были получены обработчиком (так что единственная ошибка - это оба). Кроме того, из того, что вы показываете, видно, чтоcc
запускаетicc
и не ждет его ...? (Вы уверены? Для меня это звучит очень странно.) - person zdim   schedule 06.06.2019wait 31589
(или что-то подобное), поскольку вы не знаете, какой PID дочернего элемента находится в текущем прогоне (он, скорее всего, отличается от того, что было в предыдущих прогонах). - person zdim   schedule 06.06.2019local $?
- если он предназначен для защиты вещей вне обработчика, который выиграл не работает: обработчик получает сигнал о завершившемся дочернем элементе, поэтому обратные кавычки (waitpid, который запускается системой для него) просто ничего не имеют, поэтому -1. - person zdim   schedule 06.06.2019