6

以前对这个问题的回答主要集中在分叉上:

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

假设我有一个名为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,只是正常杀死)

sleep.pl 还在睡觉。

我想我的问题的解决方案涉及一个 SIG 处理程序,但是我需要在处理程序中添加什么来杀死子进程?

4

3 回答 3

4

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

于 2009-04-22T23:55:30.547 回答
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
于 2009-04-23T09:10:35.143 回答
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( @_ );
    }
}

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

于 2010-07-06T20:21:20.723 回答