【问题标题】:perl alarm with subprocess带有子进程的perl警报
【发布时间】:2011-12-09 22:22:28
【问题描述】:

我有一个 perl 脚本,它运行一系列用于回归测试的批处理脚本。我想在批处理脚本上实现超时。我目前有以下代码。

    my $pid = open CMD, "$cmd 2>&1 |";
    eval {
               # setup the alarm
               local $SIG{ALRM} = sub { die "alarm\n" };
               # alarm on the timeout
               alarm $MAX_TIMEOUT;
               log_output("setting alarm to $MAX_TIMEOUT\n");

               # run our exe
               while( <CMD> ) {
                       $$out_ref .= $_;
               }
               $timeRemaining = alarm 0;
            };
            if ($@) {
                    #catch the alarm, kill the executable
            }

问题是,无论我将最大超时设置为多少,警报都不会触发。我尝试过使用 Perl::Unsafe::Signals 但没有帮助。

如果我希望能够捕获它们的输出,这是执行批处理脚本的最佳方式吗?有没有其他方法可以做同样的事情,让我可以使用警报,或者除了警报之外还有其他方法可以让程序超时?

我已经构建了一个测试脚本来确认警报适用于我的 perl 和 windows 版本,但是当我运行这样的命令时它不起作用。

我在 windows 7 x64 上使用 activeperl 5.10.1 运行它。

【问题讨论】:

    标签: windows perl


    【解决方案1】:

    很难判断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;
    }
    

    相反。)

    【讨论】:

      猜你喜欢
      • 2011-09-14
      • 1970-01-01
      • 2015-10-05
      • 1970-01-01
      • 2018-11-25
      • 2011-02-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多