当主脚本被杀死时,如何杀死Perl'系统'调用?

时间:2009-04-22 23:50:01

标签: perl kill

这些问题的前瞻性答案集中在分叉上:

对于这个问题,我只是询问对'系统'功能的调用。

假设我有一个名为 sleep.pl 的脚本:

use strict;
use warnings;
sleep(300);

然后我有一个名为 kill.pl

的脚本
use strict;
use warnings;
system("sleep.pl");

我运行kill.pl并使用ps我找到kill.pl的进程ID并杀死它(不使用kill -9,只是普通的kill)

sleep.pl还在睡觉。

我想我的问题的解决方案涉及一个SIG处理程序,但是我需要将哪些内容放入处理程序以终止子进程?

3 个答案:

答案 0 :(得分:3)

使用setsid使您的流程成为新的组长。然后,您可以将kill发送到组ID并终止属于该组的所有进程。您从leader进程生成的所有进程都将继承组ID并属于您新创建的组。所以向团队发送一个杀戮将杀死他们。唯一棘手的事情是为了能够使用setsid,你必须关闭你的标准和输出,因为这是setsid的要求。

答案 1 :(得分:3)

use strict;
use warnings;
setpgrp $$, 0;
system("sleep.pl");
END {kill 15, -$$}

但如果你需要这种方法,你就会做错事。你不应该这样做。以正确的方式运行并杀死你的杀戮过程。

$ perl -e 'system("sleep 100")' &
[1] 11928
$ ps f
  PID TTY      STAT   TIME COMMAND
 4564 pts/1    Ss     0:01 /bin/bash
11928 pts/1    S      0:00  \_ perl -e system("sleep 100")
11929 pts/1    S      0:00  |   \_ sleep 100
11936 pts/1    R+     0:00  \_ ps f
$ kill %1
[1]+  Terminated              perl -e 'system("sleep 100")'
$ ps f
  PID TTY      STAT   TIME COMMAND
 4564 pts/1    Rs     0:01 /bin/bash
11949 pts/1    R+     0:00  \_ ps f

它是如何工作的?如果你在后台运行,Shell(我的情况下是bash)应该将你的进程设置为组长。然后,如果您使用kill %?语法shell以正确的方式杀死组。比较一下:

$ perl -e 'system("sleep 100")' &
[1] 12109
$ ps f
  PID TTY      STAT   TIME COMMAND
 4564 pts/1    Rs     0:01 /bin/bash
12109 pts/1    S      0:00  \_ perl -e system("sleep 100")
12113 pts/1    S      0:00  |   \_ sleep 100
12114 pts/1    R+     0:00  \_ ps f
$ kill 12109
[1]+  Terminated              perl -e 'system("sleep 100")'
$ ps f
  PID TTY      STAT   TIME COMMAND
 4564 pts/1    Ss     0:01 /bin/bash
12124 pts/1    R+     0:00  \_ ps f
12113 pts/1    S      0:00 sleep 100

kill %?以这种方式运作:

$ perl -e 'system("sleep 100")' &
[1] 12126
$ ps f
  PID TTY      STAT   TIME COMMAND
 4564 pts/1    Rs     0:01 /bin/bash
12126 pts/1    S      0:00  \_ perl -e system("sleep 100")
12127 pts/1    S      0:00  |   \_ sleep 100
12128 pts/1    R+     0:00  \_ ps f
$ kill -12126
[1]+  Terminated              perl -e 'system("sleep 100")'
$ ps f
  PID TTY      STAT   TIME COMMAND
 4564 pts/1    Ss     0:01 /bin/bash
12130 pts/1    R+     0:00  \_ ps f

答案 2 :(得分:2)

你的问题确实是更为笼统的“如何确保孩子在父母去世时死亡”问题的具体例子。没有那种解决方法。 system()没什么特别之处;它只是分叉一个子进程并等待它退出。

system()大致是这样的:

sub system 
{
    my $kidpid = fork;
    if ( $kidpid )
    {
        waitpid $kidpid; 
          # parent process blocks here waiting for the child process to return
    }
    else
    {
        exec( @_ );
    }
}

杀死进程组是您唯一的选择。