程序的行为根据调用fork的位置而改变

时间:2016-02-29 04:09:27

标签: c linux unix

我正在制作一个小程序,用管道和文件描述符来熟悉它,花了很多时间调试一个没有意义的问题。

我花了很多时间以为我误解了文件描述符,只是程序行为不同,这取决于我使用fork的位置。

int main(void)
{
int fid;
int p[2];
pipe(p);
char buf[20];

fid = fork();
if (fid==0){
    close(p[1]);
    dup2(p[0],0);
    close(p[0]);
    execlp("cat","cat",(char *)NULL);

}
else{
    close(p[0]);
    dup2(p[1],1);
    close(p[1]);
    execlp("ls","ls",(char *)NULL); 
}

return 0;
}

给出了该目录中预期的输出结果。 ls out put用管道传送给猫。

如果我将叉线移到管道(p)上方;我不会得到任何输出。我不明白为什么会这样?

2 个答案:

答案 0 :(得分:1)

所以你想知道为什么会这样:

pipe(p);
fid = fork();

而这不是:

fid = fork();
pipe(p);

原因非常简单:在第一种情况下,进程创建一个管道,然后分成两个(两个进程都可以访问管道)。

在第二种情况下,进程分成两个,然后两个进程中的每一个都创建自己的管道,与另一个进程无关。

因此,在第一种情况下,一个进程写入管道,另一个进程从中读取。在第二种情况下,一个进程写入管道,另一个进程从读取另一个管道,显然没有收到数据,因为它是一个不同的管道。

答案 1 :(得分:0)

fork系统调用会创建调用它的进程的完全重复。这包括任何文件描述符。通过fork调用现在,每个进程都会通过pipe调用创建管道的末尾。这就是为什么每个进程都关闭管道的另一端,然后一个进程调用dup2将管道挂钩到stdout,而另一个进程将管道挂钩到stdin。这是流程的沟通方式。但是如果在fork调用之前调用pipe,则每个进程都创建了自己的独立管道。