5

私はデバッグユーティリティforkを書いていますが、その子の終了SIGCHLDがその親にトリガーされるのを防ぎながら、子にしたいです。私はまだ、他の子供たちがSIGCHLD終了時に通常どおりに発生することを望んでいます。

fork既存のハンドラーをトリガーしたくないのでこれを行いたいのです$SIG{CHLD}が、それでも他の子にそれをトリガーさせたいのです。つまり、新しい子を隔離したいのですが、既存の子の管理に干渉したくありません。

$SIG{CHLD}元のハンドラーをいつ呼び出す必要があるかを適切に検出できるとは思わないため、カスタムハンドラーをローカルにインストールすることには慎重です。たとえば、ローカル$SIG{CHLD}ハンドラーをインストールするSIGCHLDと、子をスポーンして親waitpidを終了させると、必ずシグナルを受信します。ただし、それSIGCHLDは他の子も終了したかどうかを示すものではないため、元のハンドラーを呼び出すかどうかはわかりません。

プロセスがその親 pid を変更できないことを調査しました。子のプロセス グループ ID またはセッション ID を変更することが役立つかどうかはわかりません。

SIGCHLD特定の子が親でトリガーするのを防ぐことさえ可能ですか? 既存のハンドラーが予期していなかった子$SIG{CHLD}のシグナルを受信したときに、正しいことを実行することに依存する必要がありますか?SIGCHLD

そのデバッグ ユーティリティを実装するためのより良い方法があるかもしれませんが (ある場合はお知らせください)、POSIX が子に対するそのようなきめ細かな制御を提供するかどうかはまだ疑問に思っており、私のジレンマに対する Perl ソリューションを探しています。

4

2 に答える 2

2

移植可能に完全に防ぐことはできませんSIGCHLDが、シグナル ハンドラが適切に記述されていれば、waitpid を孤立させることでデバッグ ツールの pid が返されるのを防ぐことができます。

use Signal::Mask;
sub start_background_child {
  local $Signal::Mask{CHLD} = 1;
  my $first = fork;
  croak "fork failed: $!" if not defined $first;
  if ($first) {
    waitpid $first, 0;
    return;
  }

  my $second = fork;
  croak "fork failed: $!" if not defined $second;
  exit if $second;

  your_stuff_here();
}
于 2014-03-05T16:30:29.577 に答える
1

親子関係を断ち切るために、特別な子 (fork を 2 回実行) をデーモン化できると思います。プロセスが作成されたときにまだ を受け取りSIGCHLDます。それが受け入れられるかどうかはわかりません。

sub start_special_child {
    return if fork;     # run rest of this routine in child process
    fork && exit;       # run rest of this routine in grandchild process
                        # the  exit  here triggers SIGCHLD in the parent
    ...                 # now run your special process
    exit;               # exit here does not trigger SIGCHLD
}

もう 1 つのアプローチは、子プロセスのプロセス ID を追跡し、どのプロセスがハンドラーwaitpidをトリガーしたかを把握するために使用することです。SIGCHLD

$SIG{CHLD} = \&sigchld_handler;
$pid1 = start_child_process();
$pid2 = start_child_process();
$pid3 = start_child_process();
$pidS = start_special_child_process();

sub sigchld_handler {
    $pid = waitpid -1, WNOHANG;     # use POSIX ':sys_wait_h'
    return if $pid == $pidS;
}
于 2014-03-05T16:04:24.440 に答える