2011-11-09 4 views
1

シェルプロセスのパイプ演算子を使用して標準出力を別のプロセス(下流プロセスと呼ばれます)にパイプするLinuxプロセス(メインプロセスと呼ぶ) (|)。ダウンストリームプロセスがクラッシュした場合、メインプロセスはSIGPIPEシグナルを受信するように設定されます。残念ながら、メインプロセスがstdoutに書き込むまで、SIGPIPEは呼び出されません。ダウンストリームプロセスが終了したとすぐに伝える方法はありますか?Unixパイプ内の下流プロセスがクラッシュしたかどうかを確認する方法

1つのアプローチは、下流のプロセスに連続的に書き込むことですが、それは無駄に見えます。もう1つのアプローチは、すべての関連プロセスを監視する独立したウォッチドッグプロセスを持つことですが、それは複雑です。あるいは、シグナルをトリガするためにselect()を使用する方法があります。私は主なプロセスがすべてこれを行うことができることを望んでいます。

+0

ダウンストリームプロセスがクラッシュしたときにすぐに知っておく必要がありますか、次回に書き込むときにクラッシュしたことを知っていれば十分でしょうか? – zwol

+0

私がこの質問に言及したように、私は、次の書き込み(私の文脈では不確定な時間に来るかもしれない)ではなく、下流プロセスがより早くクラッシュすることを知りたいと思います。 –

答えて

3

は "読むための準備" になったときに受信機がクラッシュ:

$ gcc -Wall select-downstream-crash.c -o select-downstream-crash 
$ gcc -Wall crash-in-five-seconds.c -o crash-in-five-seconds 
$ ./select-downstream-crash | ./crash-in-five-seconds 
    ... five seconds pass ... 
stdout is ready for reading 
Segmentation fault 

選択-下流crash.c

#include <err.h> 
#include <stdio.h> 
#include <sys/select.h> 
#include <unistd.h> 

int main(void) 
{ 
    fd_set readfds; 
    int rc; 

    FD_ZERO(&readfds); 
    FD_SET(STDOUT_FILENO, &readfds); 

    rc = select(STDOUT_FILENO + 1, &readfds, NULL, NULL, NULL); 
    if (rc < 0) 
     err(1, "select"); 

    if (FD_ISSET(STDOUT_FILENO, &readfds)) 
     fprintf(stderr, "stdout is ready for reading\n"); 

    return 0; 
} 

クラッシュ・イン・5 -seconds.c

#include <stdio.h> 
#include <unistd.h> 

int main(void) 
{ 
    sleep(5); 
    putchar(*(char*)NULL); 
    return 0; 
} 

私はLinuxでこれを試しましたが、別の場所で動作するかどうかはわかりません。この観察を説明するいくつかの文書を見つけることは良いことです。

0

メインプロセスforkが他のプロセスの場合は、終了時にSIGCHLDという通知が表示されます。

これは、標準出力ファイルディスクリプタを表示さ
+0

右。残念ながら、下流のプロセスはシェルによって作成され、パイプ演算子によって接続されます。下流にある。 –

関連する問題