我正在制作一个小程序,用管道和文件描述符来熟悉它,花了很多时间调试一个没有意义的问题。
我花了很多时间以为我误解了文件描述符,只是程序行为不同,这取决于我使用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)上方;我不会得到任何输出。我不明白为什么会这样?
答案 0 :(得分:1)
所以你想知道为什么会这样:
pipe(p);
fid = fork();
而这不是:
fid = fork();
pipe(p);
原因非常简单:在第一种情况下,进程创建一个管道,然后分成两个(两个进程都可以访问管道)。
在第二种情况下,进程分成两个,然后两个进程中的每一个都创建自己的管道,与另一个进程无关。
因此,在第一种情况下,一个进程写入管道,另一个进程从中读取。在第二种情况下,一个进程写入管道,另一个进程从读取另一个管道,显然没有收到数据,因为它是一个不同的管道。
答案 1 :(得分:0)
fork
系统调用会创建调用它的进程的完全重复。这包括任何文件描述符。通过fork
调用现在,每个进程都会通过pipe
调用创建管道的末尾。这就是为什么每个进程都关闭管道的另一端,然后一个进程调用dup2
将管道挂钩到stdout
,而另一个进程将管道挂钩到stdin
。这是流程的沟通方式。但是如果在fork
调用之前调用pipe
,则每个进程都创建了自己的独立管道。