【问题标题】:How can I kill Perl 'system' calls when the main script is killed?当主脚本被杀死时,我怎样才能杀死 Perl 的“系统”调用?
【发布时间】:2009-04-22 23:50:00
【问题描述】:

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

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

假设我有一个名为 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 处理程序,但我需要在处理程序中添加什么来终止子进程?

【问题讨论】:

  • 这需要额外的标签。 [杀死] 例如。

标签: perl kill


【解决方案1】:

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

【讨论】:

    【解决方案2】:
    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
    

    【讨论】:

    • 总而言之,使用负 PID。
    【解决方案3】:

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

    system() 大致是这样的:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-01-23
      • 2017-01-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多