我创建了一个简单的管道,并使用forked(子)进程将ls -l /usr/bin
命令的结果写入其中。然后在主(父)过程中,我等待孩子完成。
int fd[2];
char* arg[] = {"ls", "-l" , "/usr/bin/", NULL};
pipe(fd);
if (fork()==0) //child
{
dup2(fd[1], 1);
close(fd[0]);
close(fd[1]);
execvp(arg[0],arg);
}
else //parent
{
// close(fd[0]);
close(fd[1]);
wait(NULL);
}
在我执行dup2
之后的子进程中,我关闭了两端的管道,因为我不再需要它们了。在父级中,我只关闭写端,因为我需要读取结束。
如果执行此代码,它将停止。 但是,如果命令是ls -l ~/Desktop/
或类似的东西,它会成功终止。
显然ls -l /usr/bin
命令比ls -l ~/Desktop/
花费的时间更长,但我认为它们仍无关紧要,两者都必须终止。
在父母中,如果我也关闭管道的读取端,程序将终止(我不想要)。
这种行为的原因是什么?是否有任何解决方法可以克服它?
答案 0 :(得分:2)
问题在于管道的容量有限(POSIX允许非常小,如4 KiB; Linux可能允许最高约64 KiB,而Mac OS X允许最高64 KiB)。在写入过程写入大量数据而没有读取过程进行读取之后,它会被阻塞,直到读取过程读取某些数据,或者最后一个读取过程消失并且没有剩余的过程可以读取数据。
管道用于并发执行程序。您通过尝试在下次启动之前完成第一个程序来强制执行顺序执行。这是不正确的。您需要确保在等待它们完成之前启动管道中的所有进程