О чем, черт возьми, я думал? Вам не нужен фоновый процесс для этой задачи. Вам просто нужно следовать примеру в функции perldoc -f alarm
и обернуть свой чувствительный ко времени код в блок eval
.
my $command = "adb shell cd /data/app; ./iperf -u -s -p 5001";
my @output;
eval {
local $SIG{ALRM} = sub { die "Timeout\n" };
alarm 30;
@output = `$command`;
alarm 0;
};
if ($@) {
warn "$command timed out.\n";
} else {
print "$command successful. Output was:\n", @output;
}
Внутри блока eval
вы можете фиксировать выходные данные обычным способом (с помощью обратных кавычек или qx()
или readpipe
). Хотя, если время ожидания истекло, никакого вывода не будет.
Если вам не нужны выходные данные (или вы не против взломать какое-то межпроцессное взаимодействие), почти защищенная от дурака альтернатива - установить будильник и запустить вызов system
в дочернем процессе.
$command = "adb shell cd /data/app; ./iperf -u -s -p 5001";
if (($pid = fork()) == 0) {
# child process
$SIG{ALRM} = sub { die "Timeout\n" }; # handling SIGALRM in child is optional
alarm 30;
my $c = system($command);
alarm 0;
exit $c >> 8; # if you want to capture the exit status
}
# parent
waitpid $pid, 0;
waitpid
вернется, когда будет завершена команда ребенка system
, или , когда сработает тревога ребенка и убьет ребенка. $?
будет содержать код завершения системного вызова или что-то еще (142 в моей системе) для необработанного SIGALRM или 255, если ваш обработчик SIGALRM вызывает die
.