如何使可能挂起的分叉进程超时?
我正在编写一个 Perl 脚本,它将写入一些输入并将这些输入发送到外部程序。该程序挂起的可能性虽小但非零,我想将其超时:
my $pid = fork;
if ($pid > 0){
eval{
local $SIG{ALRM} = sub { die "TIMEOUT!"};
alarm $num_secs_to_timeout;
waitpid($pid, 0);
alarm 0;
};
}
elsif ($pid == 0){
exec('echo blahblah | program_of_interest');
exit(0);
}
就目前情况而言,在 $num_secs_to_timeout 之后,program_of_interest 仍然存在。我尝试在 $SIG{ALRM}
的匿名子例程中杀死它,如下所示:
local $SIG{ALRM} = sub{kill 9, $pid; die "TIMEOUT!"}
但这不会执行任何操作。 program_of_interest 仍然存在。我该如何杀死这个进程?
I am writing a Perl script that will write some inputs and send those inputs to an external program. There is a small but non-zero chance that this program will hang, and I want to time it out:
my $pid = fork;
if ($pid > 0){
eval{
local $SIG{ALRM} = sub { die "TIMEOUT!"};
alarm $num_secs_to_timeout;
waitpid($pid, 0);
alarm 0;
};
}
elsif ($pid == 0){
exec('echo blahblah | program_of_interest');
exit(0);
}
As it stands now, after $num_secs_to_timeout, program_of_interest still persists. I tried to kill it in the anonymous subroutine for $SIG{ALRM}
as follows:
local $SIG{ALRM} = sub{kill 9, $pid; die "TIMEOUT!"}
but this doesn't do anything. program_of_interest is still persisting. How do I go about killing this process?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我能够通过终止进程组成功终止我的 exec()ed 进程,如问题 在 perl 中,当使用 open 创建 child 时杀死 child 及其子组件。我修改了我的代码如下:
超时后,program_of_interest被成功杀死。
I was able to successfully kill my exec()ed process by killing the process group, as shown as the answer to question In perl, killing child and its children when child was created using open. I modified my code as follows:
After timeout, program_of_interest is successfully killed.
上面的代码(由 strictrude27 编写)并没有开箱即用,因为 -$PID 是大写的。
(顺便说一句:还有: http://www.gnu.org /software/coreutils/manual/html_node/timeout-invocation.html)
这是一个测试示例:
The above code (by strictlyrude27) didn't work out of the box, because -$PID is spelt in capitals.
(BTW: there's also: http://www.gnu.org/software/coreutils/manual/html_node/timeout-invocation.html)
Here's an example with test:
嗯,经过一些小的修改,你的代码对我有用 - 我认为这些修改是你自己为了使代码成为通用示例而进行的更改。
因此,这给我留下了两个想法:
祝你好运...
Hmmm your code works for me, after some minor modifications - which I assume are changes made by yourself to make the code into a generic example.
So that leaves me with two ideas:
Good luck...
可以忽略 SIGKILL 的唯一方法是进程陷入不可中断的系统调用中。检查挂起进程的状态(使用
ps aux
),如果状态为D,则该进程无法被杀死。您可能还想通过输出某些内容来检查该函数是否正在被调用。
The only way SIGKILL can be ignored is if the process is stuck in a system call which is uninterruptible. Check the state of the hung process (with
ps aux
) if the state is D, then the process can't be killed.You might also want to check that the function is being called by outputting something from it.