【问题标题】:How to handle pipes in this special case在这种特殊情况下如何处理管道
【发布时间】:2016-05-16 23:37:50
【问题描述】:

我创建了一个简单的管道,并使用分叉(子)进程将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/ 花费更多时间,但我认为这仍然没有关系,它们都必须终止。

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

这种行为的原因是什么?有什么办法可以克服吗?

【问题讨论】:

  • 你为什么不从管道读取数据?

标签: c shell pipe fork posix


【解决方案1】:

问题在于管道的容量是有限的(POSIX 允许的容量非常小,例如 4 KiB;Linux 最多允许大约 64 KiB,Mac OS X 最多允许 64 KiB)。在写入进程写入这么多数据而没有读取进程执行读取的情况下,它会被阻塞,直到读取进程读取一些数据,或者最后一个读取进程死亡并且没有进程可以读取数据。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-26
    相关资源
    最近更新 更多