【发布时间】:2010-12-16 15:16:01
【问题描述】:
我想在 Linux 操作系统上的 C 程序中执行以下操作:
- 使用系统调用(或 2 个)创建 PIPE
- 使用 exec() 执行新进程
- 将进程的 STDIN 连接到之前创建的管道。
- 将进程的输出连接到另一个 PIPE。
这个想法是为了性能目的而规避任何驱动器访问。
我知道使用 PIPE 系统调用创建管道非常简单 并且我可以使用 popen 来创建用于输入或输出目的的管道。
但是您将如何对输入和输出执行此操作?
【问题讨论】:
我想在 Linux 操作系统上的 C 程序中执行以下操作:
这个想法是为了性能目的而规避任何驱动器访问。
我知道使用 PIPE 系统调用创建管道非常简单 并且我可以使用 popen 来创建用于输入或输出目的的管道。
但是您将如何对输入和输出执行此操作?
【问题讨论】:
根据您的需要,您可能会发现使用 mkfifo(1) 来创建命名管道并让您的进程读/写该文件会更容易。虽然文件是在文件系统中命名的,但使用匿名管道的开销不应该是可观的。
【讨论】:
你需要非常小心管道:
注意有多少关闭,尤其是在孩子中。如果使用 dup2(),则不必显式关闭标准输入和输出;但是,如果您执行显式关闭,则 dup() 可以正常工作。另请注意, dup() 和 dup2() 都不会关闭重复的文件描述符。如果您省略关闭管道,则两个程序都无法正确检测到 EOF;当前进程仍然可以写入管道的事实意味着管道上没有EOF,程序将无限期挂起。
请注意,此解决方案不会改变孩子的标准误差;它与父级的标准错误位于同一位置。通常,这是正确的。如果您有特定要求以不同方式处理来自子级的错误消息,那么也要对子级的标准错误采取适当的措施。
【讨论】:
最简单的方法可能是执行/bin/sh,这样您就可以使用熟悉的shell语法来指定管道并减轻所有复杂性。
类似:
execlp("sh", "-c", "cat /dev/zero | cat > /dev/null", NULL);
【讨论】: