使用Fork和Dup的Unix管道

Jac*_*cob 2 c unix pipe process

让我们说在我的程序中我想执行两个子进程,一个执行"ls -al"命令,然后将其传递到"wc"命令并在终端上显示输出.到目前为止,我如何使用管道文件描述符执行此操作我编写的代码:一个示例将非常有用

int main(int argc, char *argv[]) {
    int pipefd[2];
    int pipefd2[2];

    pipe(pipefd2);
    if ((fork()) == 0) {
       dup2(pipefd2[1],STDOUT_FILENO);
       close(pipefd2[0]);
       close(pipefd2[1]);
       execl("ls", "ls","-al", NULL);
       exit(EXIT_FAILURE);
    } 

    if ((fork()) == 0){
        dup2(pipefd2[0],STDIN_FILENO);
        close(pipefd2[0]);
        close(pipefd2[1]);
        execl("/usr/bin/wc","wc",NULL);
        exit(EXIT_FAILURE);
    }
    close(pipefd[0]);
    close(pipefd[1]);
    close(pipefd2[0]);
    close(pipefd2[1]);
}
Run Code Online (Sandbox Code Playgroud)

msw*_*msw 10

你的示例代码在语法和语义上都被破坏了(例如pipefd2没有被删除,pipefd和pipefd2之间的混淆等)因为这有点像家庭作业,请确保你理解我的注释,并询问你是否需要更多.我省略了对pipe,fork和dup的错误检查,但理想情况下它们应该在那里.

int main(int argc, char *argv[]) {
    int pipefd[2];
    pid_t ls_pid, wc_pid;

    pipe(pipefd);

    // this child is generating output to the pipe
    //
    if ((ls_pid = fork()) == 0) {
        // attach stdout to the left side of pipe
        // and inherit stdin and stdout from parent
        dup2(pipefd[1],STDOUT_FILENO);
        close(pipefd[0]);              // not using the right side

        execl("/bin/ls", "ls","-al", NULL);
        perror("exec ls failed");
        exit(EXIT_FAILURE);
    } 

    // this child is consuming input from the pipe
    //
    if ((wc_pid = fork()) == 0) {
        // attach stdin to the right side of pipe
        // and inherit stdout and stderr from parent
        dup2(pipefd[0], STDIN_FILENO);

        close(pipefd[1]);              // not using the left side
        execl("/usr/bin/wc", "wc", NULL);
        perror("exec wc failed");
        exit(EXIT_FAILURE);
    }

    // explicitly not waiting for ls_pid here
    // wc_pid isn't even my child, it belongs to ls_pid

    return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)

  • 你最后的评论是否正确?他们不是父母一方的孩子吗? (3认同)
  • 关闭一个“dup”文件描述符会关闭另一个文件描述符是不正确的。关闭一个文件只会删除打开文件的一个句柄。文件本身不会关闭,直到它的所有“dup”文件描述符都被关闭。 (2认同)
  • 哦,你*应该*关闭父级中的“pipefd”文件描述符 - 它不需要它们(并且读取子级不会看到文件结尾,直到父级关闭其在写入端的句柄)。同样,“close()”只会删除您传递给它的句柄,直到“每个”进程中的“所有”句柄都关闭后,底层管道才会关闭。 (2认同)