Linux管道作为输入和输出

时间:2009-11-14 17:25:42

标签: c linux ipc pipe

我想在Linux操作系统上的C程序中执行以下操作:

  • 使用系统调用(或2)
  • 创建PIPE
  • 使用exec()
  • 执行新进程
  • 将流程的STDIN连接到之前创建的管道。
  • 将流程的输出连接到另一个PIPE。

这个想法是出于性能目的绕过任何驱动器访问。

我知道使用PIPE系统调用创建管道非常简单 并且我可以使用popen来创建用于输入或输出目的的管道。

但是你会如何为输入和输出做这个呢?

3 个答案:

答案 0 :(得分:7)

你需要对管道非常小心:

  1. 两次调用pipe(),一次用于管道到子级,一次用于管道输出,产生4个文件描述符。
  2. 调用fork()。
  3. 在孩子:
    • 在标准输入(文件描述符0)上调用close()。
    • 调用dup() - 或dup2() - 使管道到子的读取结束为标准输入。
    • 在pipe-to-child的读取结束时调用close()。
    • 在pipe-to-child的写入结束时调用close()。
    • 在标准输出(文件描述符1)上调用close()。
    • 调用dup() - 或dup2() - 使从子管道到标准输出的写入结束
    • 在pipe-from-child的写入端调用close()。
    • 在pipe-from-child的读取端调用close()。
    • 执行所需的程序。
  4. 在父母:
    • 在管道到孩子的读取结束时调用close。
    • 在来自孩子的管道的写入结束时调用close。
    • 循环向送孩子写入端的子节点发送数据,并从子节点读取端读取子节目数据
    • 当没有更多要发送给孩子时,请关闭管道到孩子的结尾。
    • 收到所有数据后,关闭管道从孩子的读取结束。
  5. 注意有多少关闭,特别是在孩子身上。如果使用dup2(),则不必显式关闭标准输入和输出;但是,如果您执行显式关闭,dup()可以正常工作。另请注意,dup()和dup2()都不会关闭重复的文件描述符。如果省略关闭管道,那么两个程序都无法正确检测到EOF;当前进程仍然可以写入管道的事实意味着管道上没有EOF,程序将无限期挂起。

    请注意,此解决方案不会改变孩子的标准错误;它与父级的标准错误位于同一位置。通常,这是正确的。如果您有特定的要求,来自孩子的错误消息的处理方式不同,那么也要对孩子的标准错误采取适当的措施。

答案 1 :(得分:1)

根据您的需要,您可能会发现使用mkfifo(1)创建命名管道并让您的进程读/写该文件更容易。虽然文件在文件系统中命名,但使用匿名管道的开销不应该是明显的。

答案 2 :(得分:0)

最简单的方法可能是执行/bin/sh,这样您就可以使用熟悉的shell语法来指定管道并卸载所有复杂性。

类似的东西:

execlp("sh", "-c", "cat /dev/zero | cat > /dev/null", NULL);