如何判断Unix管道中的下游进程是否已崩溃

时间:2011-11-09 23:31:38

标签: linux unix crash pipe sigpipe

我有一个Linux进程(让我们称之为主进程),其标准输出通过shell的管道运算符(|)传送到另一个进程(称为下游进程)。主进程设置为在下游进程崩溃时接收SIGPIPE信号。不幸的是,在主进程写入stdout之前,不会引发SIGPIPE。有没有办法告诉下游流程何时终止?

一种方法是不断写入下游流程,但这似乎很浪费。另一种方法是使用单独的监视程序来监视所有相关进程,但这很复杂。或者也许有一些方法可以使用select()来触发信号。我希望主要过程本身可以做到这一切。

2 个答案:

答案 0 :(得分: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

选择-下游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;
}

<强>碰撞在-五seconds.c

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

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

我在Linux上试过这个,但不知道它是否会在其他地方运行。很高兴找到解释这一观察结果的文件。

答案 1 :(得分:0)

如果主进程fork是其他进程,则退出时会收到SIGCHLD次通知。