![](/img/trans.png)
[英]How can I kill forked processes that take too long in my perl script without timing out the forked process?
[英]Timing out a forked process
我在多個處理器上運行蒙特卡洛,但掛了很多。 因此,我將這段Perl代碼組合在一起,以殺死掛起蒙特卡洛的迭代,然后轉到下一個迭代。 但是我遇到了一些錯誤,我還沒有弄清楚。 我認為它睡得太久了,它將在查找之前刪除out.mt0文件。 這是代碼:
my $pid = fork();
die "Could not fork\n" if not defined $pid;
if ($pid == 0) {
print "In child\n";
system("hspice -i mont_read.sp -o out -mt 4"); wait;
sleep(.8); wait;
exit(0);
}
print "In parent \n";
$i = 0;
$mont_number = $j - 1;
out: while (1) {
$res = waitpid($pid, WNOHANG);
if ($res == -1) {
print "Successful Exit Process Detected\n";
system("mv out.mt0 mont_read.mt0"); wait;
sleep(1); wait;
system("perl monte_stat.pl > rel_out.txt"); wait ;
system("cat stat_result.txt rel_out.txt > stat_result.tmp"); wait;
system("mv stat_result.tmp stat_result.txt"); wait;
print "\nSim #$mont_number complete\n"; wait;
last out;
}
if ($res != -1) {
if ($i >= $timeout) {
$hang_count = $hang_count+1;
system("killall hspice"); wait;
sleep(1);
print("time_out complete\n"); wait;
print "\nSim #$mont_number complete\n"; wait;
last out;
}
if ($i < $timeout) {
sleep $slept; wait;
}
$i = $i+1;
}
}
這是錯誤:
Illegal division by zero at monte_stat.pl line 73, line 2. mv: cannot stat `out.mt0': No such file or directory Illegal division by zero at monte_stat.pl line 73, line 1. mv: cannot stat `out.mt0': No such file or directory Illegal division by zero at monte_stat.pl line 73, line 1. mv: cannot stat `out.mt0': No such file or directory Illegal division by zero at monte_stat.pl line 73. mv: cannot stat `out.mt0': No such file or directory Illegal division by zero at monte_stat.pl line 73. mv: cannot stat `out.mt0': No such file or directory mv: cannot stat `out.mt0': No such file or directory mv: cannot stat `out.mt0': No such file or directory Illegal division by zero at monte_stat.pl line 73, line 3. mv: cannot stat `out.mt0': No such file or directory Illegal division by zero at monte_stat.pl line 73, line 1. mv: cannot stat `out.mt0': No such file or directory
誰能給我一個在哪里調試的想法。 謝謝
根據錯誤,您的hslice
似乎崩潰了。 但是還有其他問題。
這首先是一個盡可能接近您的代碼的工作示例。
use warnings;
use strict;
use feature 'say';
use POSIX qw(:sys_wait_h);
$| = 1;
my ($timeout, $duration, $sleep_time) = (5, 10, 1);
my $pid = fork // die "Can't fork: $!";
if ($pid == 0)
{
exec "echo JOB STARTS; sleep $duration; echo JOB DONE";
die "exec shouldn't return: $!";
}
say "Started $pid";
sleep 1;
my $tot_sec;
while (1)
{
my $ret = waitpid $pid, WNOHANG;
if ($ret > 0) { say "Child $ret exited with: $?"; last; }
elsif ($ret < 0) { say "\nNo such process ($ret)"; last; }
else { print " . " }
sleep $sleep_time;
if (($tot_sec += $sleep_time) > $timeout) {
say "\nTimeout. Send 15 (SIGTERM) signal to the process.";
kill 15, $pid;
last;
}
}
將(工作的) $duration
設置為3
,比$timeout
短,我們得到
Started 16848 JOB STARTS . . . JOB DONE Child (JOB) 16848 exited with: 0
當$duration
設置為10
我們得到
Started 16550 JOB STARTS . . . . . Timeout. Send 15 (SIGTERM) signal to the process.
作業就被殺死(再等待5秒鍾– JOB DONE
不會出現)。
對問題代碼的注釋
如果您只是為了執行一項任務而fork
,則沒有理由使用system
。 只是執行那個程序
無需等待 system
之后,這是錯誤的。 system
包括一個等待
wait
不屬於print
和sleep
,這是錯誤的
無需為了殺死進程而killall
如果最終使用system
該程序將在具有另一個PID的新進程中運行。 然后,需要更多的時間來找到該PID並殺死它。 例如,請參見Proc :: ProcessTable和此文章 。
上面的代碼需要檢查該進程是否確實被終止
替換您的命令行而不是echo ...
並根據需要添加對它的檢查。
另一種選擇是簡單地睡眠$timeout
時間,然后檢查作業是否完成(孩子退出了)。 但是,使用您的方法可以在輪詢時執行其他操作。
另一種選擇是使用警報 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.