(2005-08の一覧)
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31

2005-08-19 Fri (他の年の同じ日: 2007)

子プロセス孫プロセスひ孫プロセス...を一気に殺す
2005-08-19-1 / カテゴリ: [programming][perl] / [permlink]

少なくとも子プロセスの pid はわかってるはずだから、プロセスグループ ID を取得して、kill する。
$pgrp = getpgrp $chld_pid;
kill -9, $pgrp;
kill の第一引数は、送りたいシグナル番号。

かなりドンくさいけどテストコード
if ($pid[0] = fork) {
  # oya;
  local $SIG{INT} = sub {
    my $pgrp = getpgrp $pid[0];
    print "pgrp: ", $pgrp, "\n";
    print "catch ", shift, " (oya)\n";
    kill -15, $pgrp;
    exit;
  };
  &loop;
}
elsif (defined $pid[0]) {

  if ($pid[1] = fork) {
    # ko
    local $SIG{TERM} = $SIG{HUP} = sub {
      print "catch ", shift, " (ko)\n";
      exit;
    };
    &loop;
  }
  elsif (defined $pid[1]) {

    local $SIG{CHLD} = 'IGNORE';

    if ($pid[2] = fork) {
      # mago
      local $SIG{TERM} = $SIG{HUP} = sub {
        print "catch ", shift, " (mago)\n";
        exit;
      };
      &loop;
    }
    elsif (defined $pid[2]) {
      # himago
      local $SIG{TERM} = $SIG{HUP} = sub {
        print "catch ", shift, " (himago)\n";
        exit;
        };
      &loop;
    }
  }
}

sub loop {
  while (1) {
    print "sleep ";
    sleep 1;
  }
}
kill にシグナル名を与えられないのは微妙に使いにくいかな??

実行
% ./test.pl
sleep sleep sleep sleep ^Cpgrp: 7060
catch INT (oya)
catch TERM (himago)
catch TERM (mago)
catch TERM (ko)
zsh: terminated  ./test.pl
前の日 / 次の日 / 最新 / 2005-08

2013 : 01 02 03 04 05 06 07 08 09 10 11 12
2012 : 01 02 03 04 05 06 07 08 09 10 11 12
2011 : 01 02 03 04 05 06 07 08 09 10 11 12
2010 : 01 02 03 04 05 06 07 08 09 10 11 12
2009 : 01 02 03 04 05 06 07 08 09 10 11 12
2008 : 01 02 03 04 05 06 07 08 09 10 11 12
2007 : 01 02 03 04 05 06 07 08 09 10 11 12
2006 : 01 02 03 04 05 06 07 08 09 10 11 12
2005 : 01 02 03 04 05 06 07 08 09 10 11 12
2004 : 01 02 03 04 05 06 07 08 09 10 11 12

最終更新時間: 2013-05-02 16:12