Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Windows 带子进程的perl报警_Windows_Perl - Fatal编程技术网

Windows 带子进程的perl报警

Windows 带子进程的perl报警,windows,perl,Windows,Perl,我有一个perl脚本,它运行一系列用于回归测试的批处理脚本。我想在批处理脚本上实现一个超时。我目前有以下代码 my $pid = open CMD, "$cmd 2>&1 |"; eval { # setup the alarm local $SIG{ALRM} = sub { die "alarm\n" }; # alarm on the timeout

我有一个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
            }
my$pid=opencmd,“$CMD 2>&1 |”;
评估{
#设置警报
本地$SIG{ALRM}=sub{die“alarm\n”};
#超时报警
报警$MAX_超时;
日志输出(“将报警设置为$MAX\u TIMEOUT\n”);
#运行我们的exe
而(){
$$out\u ref.=$\u;
}
$timeRemaining=报警0;
};
如果($@){
#捕捉警报,杀死可执行文件
}
问题是,无论我将最大超时设置为什么,警报都不会触发。我尝试过使用Perl::Unsafe::Signals,但没有任何帮助

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

我已经构建了一个测试脚本来确认alarm在我的perl和windows版本中可以正常工作,但是当我运行这样的命令时,它就不工作了


我在windows 7 x64上使用activeperl 5.10.1运行此功能。

很难判断
报警何时起作用,系统调用何时会被
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;
}
相反。)