簡體   English   中英

計時分叉的過程

[英]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不屬於printsleep ,這是錯誤的

  • 無需為了殺死進程而killall

  • 如果最終使用system該程序將在具有另一個PID的新進程中運行。 然后,需要更多的時間來找到該PID並殺死它。 例如,請參見Proc :: ProcessTable此文章

  • 上面的代碼需要檢查該進程是否確實被終止

替換您的命令行而不是echo ...並根據需要添加對它的檢查。

另一種選擇是簡單地睡眠$timeout時間,然后檢查作業是否完成(孩子退出了)。 但是,使用您的方法可以在輪詢時執行其他操作。

另一種選擇是使用警報

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM