1

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

1つのアプローチは、ダウンストリームプロセスに継続的に書き込むことですが、それは無駄に思えます。もう1つのアプローチは、関連するすべてのプロセスを監視する個別のウォッチドッグプロセスを用意することですが、これは複雑です。または、select()を使用してシグナルをトリガーする方法があるかもしれません。メインプロセスがこれをすべて自分で実行できることを望んでいます。

4

2 に答える 2

3

レシーバーがクラッシュすると、stdoutファイル記述子が「読み取り可能」になるようです。

$ 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

select-downstream-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;
}

クラッシュインファイブセコンド.c

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

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

Linuxで試しましたが、他の場所で機能するかどうかわかりません。この観察を説明するいくつかの文書を見つけるのは素晴らしいことです。

于 2011-11-10T03:12:16.213 に答える
0

メインプロセスforkが他のプロセスであるSIGCHLD場合、それらが終了したときに通知を受け取ります。

于 2011-11-10T00:10:18.390 に答える