1

次のように機能するサーバーを処理しようとしています。

  • 親プロセスがある
  • いくつかの特別なタスクを処理する「ヘルパー」子プロセスを作成します
    • パイプで子プロセスを開きます。パイプを使用して子にコマンドを発行します。
  • また、他の多くの子プロセスを生成します (サーバーの主な目的は、さまざまなコマンドを実行することです)。

子プロセスへのパイプへの書き込みがいつ失敗したかを検出できるようにしたいと考えています。と特別通知書を発行します。

通常は$SIG{PIPE}、親プロセスでカスタム ハンドラーを作成することでこれを実現します。

ただし、私が懸念しているのは、コマンドを実行するために親が起動するプロセスの一部が、独自のパイプを開いている可能性があるという事実です。これらのパイプへの書き込みが失敗した場合は、単に SIGPIPE を無視したいと思います。

Q1. SIGPIPE ハンドラー内から、開いているパイプのどれがシグナルをスローしたかを知る方法はありますか? (私はすべての子の PID を知っているので、PID で問題ありません... または、ファイル記述子 #s を介してそれを行う方法がある場合は?)。

Q2. どういうわけか使用して問題を解決できlocal $SIG{PIPE}ますか?私の仮定は、私がする必要があるということです:

  • そのパイプに書き込む前にヘルパープロセス固有のlocal $SIG{PIPE}権利を設定する
  • do print $HELPER_PIPE(これは 1 つのサブルーチンでのみ発生します)
  • $SIG{PIPE} をDEFAULTまたはにリセットしますIGNORE
  • これら 3 つのアクションが独自のブロック スコープ内にあることを確認します。
4

2 に答える 2

5

writesyscall は、がプロセスの強制終了に成功しないと仮定して、 がトリガーEPIPEされたときと同じケースでエラーを返します。したがって、最善の策は、設定(シグナルで死なないようにするため)、使用すること(PerlIO のバッファリングを回避し、I/O エラーがすぐに通知されるようにするため)、呼び出すたびに の戻り値を確認することです。 . false を返し、設定されている場合は、閉じたパイプに書き込もうとしています。false を返し、設定されていない場合は、他に対処すべき問題があります。SIGPIPESIGPIPE$SIG{PIPE} = 'IGNORE'$fh->autoflushprintprint$!{EPIPE}print$!{EPIPE}

于 2014-03-29T02:15:18.827 に答える
3

ポータブルではわかりません。ただし、お使いの OS がこのSIG_INFO情報をサポートしていることに気付くかもしれません。Perl まで何らかの方法でそれを取得できる場合、siginfo構造体には に FD 番号を与えるフィールドが含まれていますSIGPIPE

于 2014-03-29T15:29:21.570 に答える