Windows 带子进程的perl报警
我有一个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
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;
}
相反。)