Как определить, произошел ли сбой нижестоящего процесса в канале Unix - PullRequest
1 голос
/ 10 ноября 2011

У меня есть процесс Linux (назовем его основным), чей стандартный вывод передается другому процессу (называемому нисходящим процессом) с помощью оператора конвейера оболочки (|).Основной процесс настроен на прием сигналов SIGPIPE в случае сбоя нижестоящего процесса.К сожалению, SIGPIPE не вызывается, пока основной процесс не запишет в стандартный вывод.Можно ли как-то раньше сказать, что нисходящий процесс завершен?

Один из подходов состоит в непрерывной записи в нисходящий процесс, но это кажется расточительным.Другой подход заключается в создании отдельного сторожевого процесса, который отслеживает все соответствующие процессы, но это сложно.Или, возможно, есть какой-то способ использовать select () для запуска сигнала.Я надеюсь, что основной процесс может сделать все это сам.

Ответы [ 2 ]

3 голосов
/ 10 ноября 2011

Похоже, что дескриптор файла 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, но не знаю, сработает ли это где-нибудь еще.Было бы неплохо найти документацию, объясняющую это наблюдение.

0 голосов
/ 10 ноября 2011

Если основной процесс fork с другими процессами, то при выходе он получит SIGCHLD уведомлений.

...