父子进程之间的管道问题

时间:2019-04-11 13:37:36

标签: c pipe dup2

父亲使用管道读取标准输入,并使用管道将其发送到子进程,以便子进程可以对输入执行字数统计。 打开和关闭管道p [0]和p [1]的问题。 为什么我不能dup2(p [1],1)然后写(1,buffer,1)?仅当我不使用dup2(p [1],1)来写(p [1],buffer,1)时,它才起作用。

int main(int argc, char **argv){
    int p[2];
    int n;
    char buffer[1024];
    pipe(p);
    if(!fork()){
        close(p[1]);    
        dup2(p[0],0);
        close(p[0]);
        execlp("wc","wc",NULL);
        _exit(0);
    }
    else{
        close(p[0]);
        dup2(p[1],1);
        while((n=read(0,buffer,1))>0){
            write(1,buffer,1);
        }
        close(p[1]);
        wait(NULL);
    }
    return 0;
}

1 个答案:

答案 0 :(得分:0)

  

为什么我不能dup2(p [1],1)然后写(1,buffer,1)?

您可以,尽管似乎毫无意义。但是,如果您尝试使用一种(仅)向stdout写入的I / O函数,那将更有意义。

  

仅当我不写dup2(p [1],1)的情况下写(p [1],buffer,1)时才起作用。

这取决于您所说的“作品”。当我运行您的原始代码时,该程序从不打印任何输出,也不会终止,但这并不意味着父级的写入未成功将数据发送给子级。

问题是孩子不知道何时到达输入的结尾。它正在等待其输入上的文件结束信号,只要与管道的写入端关联的任何打开文件描述符就不会出现。

如果父级不复制管道的写入端,则仅在其上打开一个文件描述符,而子级则具有一个。双方都在适当的时候关闭了它们。但是在您提供的代码中,父级将p[1]复制到文件描述符1上,因此它有两个指向管道末端的打开文件描述符。它只会关闭p[1],而文件描述符1保持打开状态,因此子级将继续等待更多输入。

如果退出,则父级将关闭FD 1,以允许孩子完成操作,但它正在等待孩子先终止。这是与I / O重定向相关的更常见的死锁错误之一。我建议您不要让父对象复制文件描述符,因为复制到FD 1上会不必要地阻止它将其标准输出用于任何其他目的。但是,如果确实重复,则必须在子项终止之前关闭两个文件描述符。