Трудно сказать, когда alarm
будет работать, когда системный вызов будет и не будет прерван SIGALRM
, как один и тот же код может вести себя по-разному в разных операционных системах и т. Д.
Если время вашей работы истекло, вы хотите убить запущенный подпроцесс.Это хороший вариант использования для тревоги бедного человека:
my $pid = open CMD, "$cmd 2>&1 |";
my $time = $MAX_TIMEOUT;
my $poor_mans_alarm = "sleep 1,kill(0,$pid)||exit for 1..$time;kill -9,$pid";
if (fork() == 0) {
exec($^X, "-e", $poor_mans_alarm);
die "Poor man's alarm failed to start"; # shouldn't get here
}
# on Windows, instead of fork+exec, you can say
# system 1, qq[$^X -e "$poor_mans_alarm"]
...
Сигнализация бедного человека выполняется в отдельном процессе.Каждую секунду он проверяет, активен ли процесс с идентификатором $pid
.Если процесс не активен, аварийный процесс завершается.Если процесс все еще остается активным через $time
секунд, он посылает сигнал уничтожения процессу (я использовал 9, чтобы сделать его недоступным, и -9, чтобы вынуть все дерево подпроцесса, ваши потребности могут отличаться).
(exec
на самом деле может и не понадобиться. Я использую его, потому что я также использую эту идиому для мониторинга процессов, которые могут пережить Perl-скрипт, который их запускал.exec
позвоните и скажите
if (fork() == 0) {
for (1..$time) { sleep 1; kill(0,$pid) || exit }
kill -9, $pid;
exit;
}
.)