LINUX.ORG.RU

Проблема с pipe-ой. Глупо звучит...


0

0

Простите за беспокойство. Вот то, что мучает меня достаточно долго:
Не могу добиться того, чтобы при порождении двух дочерних процессов и создании канала между ними оба заканчивали работу. Кто-нибудь обязательно остаётся висеть в памяти.
Вот стандартный пример, который так же после выхода оставляет процесс-потомок болтаться в памяти ожидая данных из pipe-ы (которая уже закрыта с входной стороны).

//*********************************
//* эмулятор bc, точнее плагиатор *
//*********************************
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>

#ifndef PIPE_BUF
#define PIPE_BUF 1024
#endif
main() {
    int formula[2];
    int answer[2];
    pid_t pid;
    pipe(formula);
    pipe(answer);
    if ((pid = fork()) == 0) {
        /* Calculateur. */
        (void) dup2(formula[0], 0);
        (void) dup2(answer[1], 1);
        execlp("bc", "bc", NULL);
        exit(1);
    } else if (pid != -1) {
        /* Pere */
        char line[PIPE_BUF];
        FILE* tobc = fdopen(formula[1], "w");
        FILE* frombc = fdopen(answer[0], "r");
        while (fputs("> ", stdout) != EOF &&
        fflush(stdout) == 0 &&
        fgets(line, PIPE_BUF, stdin) != NULL) {
            int n;
            if (fputs(line, tobc) == EOF ||
            fflush(tobc) != 0) {
                exit(1);
            }
            if (fscanf(frombc, "%d", &n) == 1) {
                (void) printf("# %d\n", n);
                (void) fflush(stdout);
            }
        }
    }
}
//*********************************

Если Вас не затруднит, ответьте ламеру, как надо поступать в подобной ситуации. Надо ли при окончании работы отца-потомка слать сигнал и убивать потомков? Короче, спасибо за помощь заранее!
anonymous

Re: Проблема с pipe-ой. Глупо звучит...

Добавь в конце "тела" отца
while ( wait(&status) > 0 );
почитай man wait

RSI ()

Re: Проблема с pipe-ой. Глупо звучит...

IMXO пошли от отца(или другого дитя) сигнал потомку типа SIGTERM
чтобы потомок "слетел" (оторвался) от ожидания данных от pipe
и обрабоатй SIGTERM на EXIT

Aleks_IZA ()
Ответ на: Re: Проблема с pipe-ой. Глупо звучит... от RSI

Re: Re: Проблема с pipe-ой. Глупо звучит...

RSI, спасибо большое за ответ! К сожалению просто ждать процесс потомок недостаточно -- он так и останется висеть, читая пустую pipe-у, а с ним повиснет и процесс-родитель. Я попробовал -- не работает. Всё равно -- спасибо! С уважением etarassov

anonymous ()
Ответ на: Re: Проблема с pipe-ой. Глупо звучит... от Aleks_IZA

Re: Re: Проблема с pipe-ой. Глупо звучит...

Aleks IZA, спасибо за ответ! Что произойдёт (в принципе), если запустить пайпу между двумя процессами-потомками, первый из которых просто "echo", а второй толстый-потомок, который в основном производит большие вычисления и только чуть-чуть своего времени отводит на чтение из входного потока? Понятно, что первый потомок (echo) отработает мгновенно, а второй сначала прочтёт, потом будет долго считать, а потом снова повиснет заблокированным при попытке чтения из входного потока. Если процесс-отец для этих двух "гансов" просто убъёт посылкой сигнала второй процесс после завершения работы первого, то это будет неправильный выход из ситуации. Прости, может, я просто неправильно понимаю то, что произойдёт при получении SIG_TERM... На самом деле моя проблема в следующем -- пишу minishell, при команде %> echo aa | cat Делаю следующее: minish / \ / \ / \ / \ |fork для echo | fork для cat v v minish1 minish2 |(fork, exec, wait) |(fork, exec, wait) v v echo aa >--|pipe|--> cat В результате minish2 просто виснет в ожидании cat, который в принципе может быть и очень "жирной" программой, считающей что-то сложное... Если не сложно, объясни немного подробнее, что именно ты имел в виду. Я чувствую себя тупым ламером, когда пишу подобные вопросы в форумы -- просто выхода нет -- я "должен" разобраться со всем этим. Спасибо заранее! С уважением, etarassov

anonymous ()
Ответ на: Re: Re: Проблема с pipe-ой. Глупо звучит... от anonymous

Re: Re: Re: Проблема с pipe-ой. Глупо звучит...

Мужики, я тормоз!!!
Забудте про то, что я говорил -- у меня был просто маленький bug -- я создавал pipe-у в процессе родителе и не закрывал её после вызова дочерних процессов, поэтому они ждали, пока _ВСЕ_ процессы не закроют её в том числе и родительский.
Короче, жизнь прекрасна, когда понимаешь, в чём все проблемы. ;-)

Простите за беспокойство!
:o)))))))))))))))

anonymous ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.