分叉管道子流程的最佳技术是什么?
我当前的程序需要运行另一个进程,实际上是一些由管道链接的命令。我不需要知道命令的输出,只要它们失败或成功,所以我使用fork / exec。
命令行中的等效项将是
/path/to/A arg1 arg2 | /path/to/B argB1 | /path/to/C
注意:使用脚本是不实际的,因为A / B / C将来可能会发生变化。
我使用的两种技术是:
递归前叉。在下一个分支中连接父级(输入到其父级)可用于子级的输出。
在顶层创建所有管道 然后使用循环来分叉所有可以正确连接管道的子项。
答案 0 :(得分:1)
不要递归地分叉。使B成为A的子过程并不是一个好主意。例如,如果B调用setsid
在其自己的会话中运行,则它将使用不相关的A。如果B死了,A会得到一个SIGCHILD,而不是你。特别是,您将无法获得B的返回状态。
这是在一系列管道上分叉n个子代码的草图。警告:我直接在浏览器中输入了代码;可能有很多错别字,我省略了所有错误检查。
char *executables[n];
char *args[n];
int pipes[2*n+2]; /* child i reads from */
int child_pids[n];
int ret; /*Error checking omitted; abort if ret ever becomes negative*/
ret = pipe(pipes);
for (i = 0; i < n; i++) {
ret = pipe(pipes + 2 * i + 2);
ret = fork();
if (ret == 0) {
/* Code of child i */
close(pipes[2*i+1]);
close(pipes[2*i+2]);
dup2(pipes[2*i], 0);
dup2(pipes[2*i+3], 1);
ret = execv(executables[i], args[i]);
}
close(pipes[2*i]);
close(pipes[2*i+3]);
child_pids[i] = ret;
}
/* interact with the subprocesses, then call wait or waitpid as needed */
答案 1 :(得分:0)
如果您使用的是unix,那么简单system("/path/to/A arg1 arg2 | /path/to/B argB1 | /path/to/C")
就可以执行您想要的操作。它调用shell作为/bin/sh -c $STRING_PASSED_TO_SYSTEM
。如果您想要更精细的控制,例如读取输出或写入输入的能力,请考虑C库中的popen()
例程。