带子进程的 Perl 警报
我有一个 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 运行它。
I have a perl script that runs a series of batch scripts for regression testing. I want to implement a timeout on the batch scripts. I currently have the following code.
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
}
The problem is that no matter what I set the max timeout to, the alarm is never tripped. I've tried using Perl::Unsafe::Signals but that did not help.
Is this the best way to execute the batch scripts if I want to be able to capture their output? Is there another way that would do the same thing that would allow me to use alarms, or is there another method besides alarms to timeout the program?
I have built a test script to confirm that alarm works on with my perl and windows version, but it does not work when I run a command like this.
I'm running this with activeperl 5.10.1 on windows 7 x64.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
很难判断
alarm
何时起作用,系统调用何时会或不会被SIGALRM
中断,相同的代码在不同操作系统上的行为可能会有所不同,等等。如果你的工作超时,你想终止你已经启动的子进程。这是穷人警报的一个很好的用例:
穷人的警报在单独的进程中运行。每秒,它都会检查标识符为
$pid
的进程是否仍然存在。如果进程不存在,则警报进程退出。如果进程在$time
秒后仍然存在,它会向进程发送一个终止信号(我使用 9 使其不可捕获,使用 -9 取出整个子进程树,您的需求可能会有所不同) 。(
exec
实际上可能不是必需的。我使用它是因为我还使用这个习惯用法来监视可能比启动它们的 Perl 脚本寿命更长的进程。因为这个问题不会出现这种情况,你可以跳过exec
调用并改为说。)
It's hard to tell when
alarm
will work, when a system call will and won't get interrupted by aSIGALRM
, how the same code might behave differently on different operating systems, etc.If your job times out, you want to kill the subprocess you have started. This is a good use case for the poor man's alarm:
The poor man's alarm runs in a separate process. Every second, it checks whether the process with identifier
$pid
is still alive. If the process isn't alive, the alarm process exits. If the process is still alive after$time
seconds, it sends a kill signal to the process (I used 9 to make it untrappable and -9 to take out the whole subprocess tree, your needs may vary).(The
exec
actually may not be necessary. I use it because I also use this idiom to monitor processes that might outlive the Perl script that launched them. Since that wouldn't be the case with this problem, you could skip theexec
call and sayinstead.)