Параллельные трубы не закрываются в C? - PullRequest
1 голос
/ 05 февраля 2012

Я пытаюсь передать C параллельно, но по какой-то причине он не закрывается ... он просто ждет ... Не уверен, что я описываю это хорошо, потому что я новичок в этом, но вот код

... some code up here
if(child_pid == 0) {

    if(p0 >=0 && p1 == -1) {
        dup2(p0, STDIN_FILENO);
        close(p0);
        close(p1);
    }
    else if (p0 == -1 && p1 >= 0) {
        dup2(p1, STDOUT_FILENO);
        close(p0);
        close(p1);
    }
    else if (p0 >= 0 && p1 >=0) {
        dup2(p0, STDIN_FILENO);
        dup2(p1, STDOUT_FILENO);
        close(p0);
        close(p1);
    }

      if (input)
        iofunc(input, 0);
      if (output)
        iofunc(output, 1);
    if (sub){
        command_exec (SUBSHELL_COMMAND, sub, -1, -1, -1);
        exit(0);
    }
    else {
        execvp(w[0], w);
        exit(0);
    }
}
else {
    if (waitpid (-1, &child_status, 0) != child_pid)
        child_status =-1;
    close(p0);
            close(p1);
     return WEXITSTATUS(child_status);
}
    ... some code down here

когда p0 == -1 && p1> = 0, процесс завершается / возвращается, но по какой-то причине, когда p0> = 0 && p1 == -1, процесс просто зависает, и канал не закрывается. Я выполнил команду ls | cat использует два параллельных дочерних процесса с записью ls в p1 и чтением cat из p0. Вывод был верным, но труба не закрылась, и кот никогда не выходил. Что происходит?

@ Уильям Я попробовал следующее в моем родительском блоке else, но это не сработало

close(p0);
close(p1);
if (waitpid (-1, &child_status, 0) != child_pid)
    child_status =-1;

@ Уильям, вот код, который вызывает функцию, которая вызывает вышеуказанный код

int i = 0;
    int num = 2;
    int status;
    pid_t pid;
    pid_t pids[num];
    int fd[2];
    int p = pipe(fd);
    int a;
    int b;
    //printf("pipe0:%d\n", fd[0]);
    //printf("pipe1:%d\n", fd[1]);

    for (i = 0; i < num; i++) {
      if ((pids[i] = fork()) < 0) {
        error(1,0, "child not forked");
      } else if (pids[i] == 0) {
        if (i == 0){
            b = command_exec (c->type,
                c->u.command[1],
                0, f[0], p1);
        }
        else if (i == 1){
            a = command_exec (c->type,
                c->u.command[0],
                1, p0, fd[1]);
        }
        exit(a && b);
      }

    }

    while (num > 0) {
      pid = wait(&status);
      printf("Child with PID %ld exited with status 0x%x.\n", (long)pid, status);
      num--;


    }

printf печатает только дочерний процесс, который завершает ls, но не cat

1 Ответ

1 голос
/ 05 февраля 2012

Скорее всего, родитель держит открытую другую сторону трубы.У ls есть дескриптор открытого файла на стороне записи канала в cat, но и у родительского.cat не выйдет, пока все дескрипторы файлов на стороне записи не будут закрыты.Возможно, вам просто нужно повернуть код и закрыть каналы перед вызовом waitpid, а не после.

...