&1 |"; e-6ren">
gpt4 book ai didi

windows - 带有子进程的perl警报

转载 作者:可可西里 更新时间:2023-11-01 13:26:41 25 4
gpt4 key购买 nike

我有一个 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 运行它。

最佳答案

很难说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 秒后仍然存在,它会向进程发送一个 kill 信号(我使用 9 使其不可捕获,使用 -9 取出整个子进程树,您的需求可能会有所不同) .

(exec 实际上可能不是必需的。我使用它是因为我也使用这个习惯用法来监视可能比启动它们的 Perl 脚本更长寿的进程。因为情况并非如此这个问题,你可以跳过 exec 调用并说

if (fork() == 0) {
for (1..$time) { sleep 1; kill(0,$pid) || exit }
kill -9, $pid;
exit;
}

代替。)

关于windows - 带有子进程的perl警报,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8452445/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com