Perl 对分叉过程进行计时

Perl 对分叉过程进行计时,perl,fork,Perl,Fork,我在多个处理器上运行Monte carlo,但它挂起了很多。所以我把这些perl代码放在一起,结束挂断monte carlo的迭代,然后进入下一个迭代。但是我有一些错误,我还没有弄清楚。 我认为它睡眠时间太长,它会在查找out.mt0文件之前删除它。 代码如下: my $pid = fork(); die "Could not fork\n" if not defined $pid; if ($pid == 0) { print "In child\n"; system(

我在多个处理器上运行Monte carlo,但它挂起了很多。所以我把这些perl代码放在一起,结束挂断monte carlo的迭代,然后进入下一个迭代。但是我有一些错误,我还没有弄清楚。 我认为它睡眠时间太长,它会在查找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;
    }
}
my$pid=fork();
如果未定义$pid,则die“无法分叉\n”;
如果($pid==0){
打印“在子项中”\n;
系统(“hspice-i mont_read.sp-o out-mt 4”);等待;
睡眠(.8);等待;
出口(0);
}
打印“在父项中”\n;
$i=0;
$mont_number=$j-1;
输出:while(1){
$res=waitpid($pid,WNOHANG);
如果($res==-1){
打印“检测到成功退出进程\n”;
系统(“mv out.mt0 mont_read.mt0”);等待;
睡眠(1);等待;
系统(“perl monte_stat.pl>rel_out.txt”);等待;
系统(“cat stat_result.txt rel_out.txt>stat_result.tmp”);等待;
系统(“mv stat_result.tmp stat_result.txt”);等待;
打印“\nSim#$mont_number complete\n”等待;
最后一个;
}
如果($res!=-1){
如果($i>=$timeout){
$hang_count=$hang_count+1;
系统(“killall hspice”);等待;
睡眠(1);
打印(“超时完成”);等待;
打印“\nSim#$mont_number complete\n”等待;
最后一个;
}
如果($i<$timeout){
睡眠;等待;
}
$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 monte_stat.pl第73行第2行被零非法除法。 mv:无法统计'out.mt0':没有这样的文件或目录 monte_stat.pl第73行第1行被零非法除法。 mv:无法统计'out.mt0':没有这样的文件或目录 monte_stat.pl第73行第1行被零非法除法。 mv:无法统计'out.mt0':没有这样的文件或目录 monte_stat.pl第73行被零非法除法。 mv:无法统计'out.mt0':没有这样的文件或目录 monte_stat.pl第73行被零非法除法。 mv:无法统计'out.mt0':没有这样的文件或目录 mv:无法统计'out.mt0':没有这样的文件或目录 mv:无法统计'out.mt0':没有这样的文件或目录 monte_stat.pl第73行第3行被零非法除法。 mv:无法统计'out.mt0':没有这样的文件或目录 monte_stat.pl第73行第1行被零非法除法。 mv:无法统计'out.mt0':没有这样的文件或目录 谁能告诉我在哪里调试它。
谢谢

根据错误,您的
hs许可证
正在崩溃。但还有其他问题

这里首先是一个尽可能接近您的代码的工作示例

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
设置为
10
时,我们得到

Started 16550 JOB STARTS . . . . . Timeout. Send 15 (SIGTERM) signal to the process. 从16550年开始 工作开始 . . . . . 超时。向进程发送15(SIGTERM)信号。 然后作业被终止(再等待5秒钟–完成的
作业不应显示)

对问题中代码的评论

  • 如果您
    fork
    仅运行作业,则没有理由使用
    system
    。就是那个节目

  • 不需要after
    系统
    ,这是错误的。
    系统
    包括等待

  • wait
    不属于
    print
    sleep
    之后,它是错误的

  • 无需为了终止进程而花费
    killall

  • 如果您最终使用
    system
    ,程序将在另一个PID的新进程中运行。然后需要更多的东西来找到PID并杀死它。例如,参见和

  • 上面的代码需要检查进程是否确实被终止

将命令行替换为echo…
,并根据需要添加检查

另一个选项是简单地睡眠一段时间,然后检查作业是否完成(子项退出)。然而,使用您的方法,您可以在轮询时做其他事情


另一种选择是使用。

根据错误,您的
hs许可证似乎正在崩溃。但还有其他问题

这里首先是一个尽可能接近您的代码的工作示例

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
设置为
10
时,我们得到

Started 16550 JOB STARTS . . . . . Timeout. Send 15 (SIGTERM) signal to the process. 从16550年开始 工作开始 . . . . . 超时。向进程发送15(SIGTERM)信号。 然后作业被终止(再等待5秒钟–完成的
作业不应显示)

对问题中代码的评论

  • 如果您
    fork
    仅运行作业,则没有理由使用
    system
    。就是那个节目

  • 不需要after
    系统
    ,这是错误的。
    系统
    包括等待

  • wait
    不属于
    print
    sleep
    之后,它是错误的

  • 无需为了终止进程而花费
    killall

  • 如果您最终使用
    system
    ,程序将在另一个PID的新进程中运行。然后需要更多的东西来找到PID并杀死它。例如,参见和

  • 上面的代码需要检查进程是否确实被终止

将命令行替换为echo…
,并根据需要添加检查

另一个选项是简单地睡眠一段时间,然后检查作业是否完成(子项退出)。然而,使用您的方法,您可以在轮询时做其他事情


另一种选择是使用。

发布一个最小的、完整的、可验证的示例。不要只是链接到你的代码。我在你发布的代码中没有看到任何线程。@Daskwuff我添加了线程部分。这是完整的代码:您是分叉,而不是线程。这是一个巨大的差异。@simbabque谢谢。我修改了问题。贴一个最小的,完整的,可验证的例子。不要只是链接到你的代码。我看不到任何线程