1

从下面编写的代码中,我有一个可疑点。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int main(void){

        int pid;
        int i,j;
        char c;

        int pfd[2];

        if(pipe(pfd) == -1){
                perror("pipe");
                exit(1);
        }
        // pfd[0] : process read from pfd[0]
        // pfd[1] : process write to pfd[1]

        pid = fork();

        if(pid == -1){
                perror("pid error\n");
                exit(1);
        }
        else if(pid == 0){
                close(pfd[0]);
                close(1);
                dup(pfd[1]);
                close(pfd[1]);
                execlp("./lcmd", "lcmd", NULL);
                exit(0);
        }
        else if(pid > 0){

                wait(NULL);
                close(pfd[1]);
                close(0);
                dup(pfd[0]);
                close(pfd[0]);
                execlp("./rcmd", "rcmd", NULL);
                printf("\n");
        }

        return 0;
}

这段代码解释了如何处理 dup 函数。

如您所见,如果 pid 等于 0(这意味着子进程正在进行中),则关闭管道的读取部分并关闭 stdout 文件描述符。(关闭(pdf [0]),关闭(1))。

我可以理解标准输出 fd 应该关闭,因为管道的写入部分(pdf[1])应该位于以前的标准输出位置。(重复(pdf [1]))

但是,我不明白为什么读取管道的一部分 (close(pdf[0])写入管道的一部分应该关闭 (close(pfd[1]))

即使管道是双向的,我认为没有必要声明关闭管道的其他不使用部分。

特别是 close(pdf[1]) <- 这部分,如果没有输出流(因为 stdout 和 pdf[1](管道的写入部分)在执行 execlp 函数之前已关闭),那么 execlp 函数的输出到哪里去了?

4

1 回答 1

4

管道不是双向的——读端不能被写入,写端不能被读取。

当有一个写端打开的进程时,管道上的读操作不会报告 EOF,即使写端打开的唯一进程是试图读取的进程。

因此,关闭足够多的文件描述符至关重要。根据经验,如果您使用dup2()dup()将管道的一端作为标准输入或标准输出,您应该关闭两个管道文件描述符。

于 2016-04-07T05:27:25.423 回答