在这种特殊情况下如何处理管道

时间:2016-05-16 23:37:50

标签: c shell pipe fork posix

我创建了一个简单的管道,并使用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/花费的时间更长,但我认为它们仍无关紧要,两者都必须终止。

在父母中,如果我也关闭管道的读取端,程序将终止(我不想要)。

这种行为的原因是什么?是否有任何解决方法可以克服它?

1 个答案:

答案 0 :(得分:2)

问题在于管道的容量有限(POSIX允许非常小,如4 KiB; Linux可能允许最高约64 KiB,而Mac OS X允许最高64 KiB)。在写入过程写入大量数据而没有读取过程进行读取之后,它会被阻塞,直到读取过程读取某些数据,或者最后一个读取过程消失并且没有剩余的过程可以读取数据。

管道用于并发执行程序。您通过尝试在下次启动之前完成第一个程序来强制执行顺序执行。这是不正确的。您需要确保在等待它们完成之前启动管道中的所有进程

相关问题