-1
  1. 如何使用 Perl 杀死耗时的进程或卡住的进程(通过 system命令生成)。

  2. 如何杀死使用system命令启动的进程花费太多时间或卡在某个地方。

4

3 回答 3

2

如果您希望在同一脚本中终止由 system() 调用的进程,则无法获取或终止它的 PID,因为 system() 调用在进程完成之前不会返回。相反,您可以使用 fork() 创建一个新进程,并在 exec() 新创建的进程中执行最初由 system() 调用的进程。fork() 将返回子进程的 PID,然后您可以随时使用 kill() 杀死它。

http://perldoc.perl.org/functions/fork.html

http://perldoc.perl.org/functions/exec.html

http://perldoc.perl.org/functions/kill.html

于 2013-03-01T08:37:13.957 回答
2

Perl FAQ 的第 8 节包含

如何使慢速事件超时?

使用该alarm函数,可能与信号处理程序一起使用,如Perlipc中的信号和 Camel 中的“信号”部分所述。您可以改用 CPAN 提供的更灵活的Sys::AlarmCall模块。

alarm功能并非在所有版本的 Windows 上都实现。检查您的特定 Perl 版本的文档。

perlipc 文档的“信号”部分包含

信号处理也用于 Unix 中的超时。虽然在一个eval{}块内受到安全保护,但您设置一个信号处理程序来捕获警报信号,然后安排在几秒钟内将一个信号发送给您。然后尝试您的阻止操作,在完成后清除警报,但在您退出eval{}阻止之前清除警报。如果它熄灭,您将用于die跳出街区。

这是一个例子:

my $ALARM_EXCEPTION = "alarm clock restart";
eval {
    local $SIG{ALRM} = sub { die $ALARM_EXCEPTION };
    alarm 10;
    flock(FH, 2)    # blocking write lock
                    || die "cannot flock: $!";
    alarm 0;
};
if ($@ && $@ !~ quotemeta($ALARM_EXCEPTION)) { die }

如果超时的操作是systemqx,这种技术很容易产生僵尸。如果这对您很重要,您需要自己做forkand exec,并杀死错误的子进程。

对于更复杂的信号处理,您可能会看到标准POSIX模块。遗憾的是,这几乎完全没有文档记录,但t/lib/posix.t来自 Perl 源代码分发的文件中有一些示例。

于 2013-03-01T09:36:28.273 回答
0

建议使用 fork 和 exec,主要作为安全预防措施(用户输入)。

但是,如果您不关心用户输入并且知道您已经开始使用系统的进程,那么您可以打开一个到任务列表或 ls 调用的管道,用 grep 处理它们以找到您所困扰的进程,然后发送终止信号到那些进程。

于 2013-03-01T14:09:24.433 回答