c - 平行管道没有在 C 中关闭?

标签 c process pipe

我正在尝试并行地在 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 读取。输出是正确的,但管道没有关闭并且 cat 从未退出。这是怎么回事?

@William 我在我的 parent else block 中尝试了以下内容,但它没有用

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

@William这里是调用一个调用上面代码的函数的代码

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 的子进程

最佳答案

很可能, parent 正在打开管道的另一侧。 ls 在管道的写入端有一个打开的文件描述符到 cat,但父进程也是如此。在所有写端文件描述符都关闭之前,cat 不会退出。可能,您只需要在调用 waitpid 之前而不是之后反转代码并关闭管道。

关于c - 平行管道没有在 C 中关闭?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9146380/

相关文章:

c - 在 C 中循环一个未命名的管道

c - 缓冲区溢出攻击

c - 等效于使用 for-loop 而不是 do-while-loop

java - 在单独的进程中执行 Java 应用程序

linux - SysV 消息队列数量增加

c - execve 和管道问题 - 如何读取最后的输出?

c - 我如何在 C 中进行这种巧妙的转换?

c - 使用 fread 函数读取二进制文件时出现问题

windows - CreateFile 如何以 FILE_SHARE_READ 失败并以 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE 成功?

shell - 命令来验证管道中的输入然后将其传递?