繁体   English   中英

Linux管道作为输入和输出

[英]Linux Pipes as Input and Output

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

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

这样做的目的是为了性能目的而避免访问任何驱动器。

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

但是您将如何针对输入和输出执行此操作?

您需要对管道非常小心:

  1. 调用pipe()两次,一次用于子级管道,一次用于子级管道,产生4个文件描述符。
  2. 调用fork()。
  3. 在儿童中:
    • 在标准输入(文件描述符0)上调用close()。
    • 调用dup()-或dup2()-以将管道到子级的读取结束作为标准输入。
    • 在管道到子项的读取端调用close()。
    • 在管道到子项的写入端调用close()。
    • 在标准输出(文件描述符1)上调用close()。
    • 调用dup()-或dup2()-将子管道的写入结束写入标准输出
    • 在pipe-from-child的写入端调用close()。
    • 在从子管道读取的末端调用close()。
    • 执行所需的程序。
  4. 在父母中:
    • 在读取子管道结束时调用close。
    • 在子管道发送的写入端调用关闭。
    • 循环在pipe-to-child的写端上将数据发送到child,并在pipe-from-child的读端上从child读取数据
    • 当不再发送给子代时,关闭管道到子代的写入结束。
    • 收到所有数据后,关闭子管道的读取结束。

注意关闭的数量,尤其是在孩子中。 如果使用dup2(),则不必显式关闭标准输入和输出。 但是,如果您执行显式关闭,则dup()可以正常工作。 还要注意,dup()和dup2()都不会关闭重复的文件描述符。 如果忽略关闭管道,则两个程序都无法正确检测到EOF; 当前进程仍可以写入管道的事实意味着管道上没有EOF,并且程序将无限期挂起。

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

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

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

就像是:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM