3

派生管道内衬子流程的最佳技术是什么?

我当前的程序需要运行另一个进程,这实际上是由管道链接的几个命令。如果命令失败或成功,我不需要知道命令的输出,所以我使用 fork/exec。

命令行上的等价物是

 /path/to/A arg1 arg2 | /path/to/B argB1 | /path/to/C

注意:使用脚本是不切实际的,因为它的 A/B/C 将来可能会发生变化。

我想到的两种技术是:

  1. 递归分叉。连接下一个 fork 中可用于子级的父级(输入到其父级)输出。

  2. 在顶层创建所有管道。
    然后使用一个循环来分叉所有可以正确连接管道的子节点。

4

2 回答 2

1

Don't fork recursively. Making B a subprocess of A is not a good idea. For example, if B calls setsid to run in its own session, it would take the unrelated A with it. If B dies, A would get a SIGCHILD, not you. In particular, you would not be able to obtain the return status of B.

Here's a sketch of the code to fork n children on a series of pipes. Warning: I typed the code directly into my browser; there are probably many typos, and I omitted all error checks.

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 */
于 2012-07-19T21:42:38.837 回答
0

如果您使用的是unix,那么简单的system("/path/to/A arg1 arg2 | /path/to/B argB1 | /path/to/C")就可以满足您的需求。它调用一个 shell 作为/bin/sh -c $STRING_PASSED_TO_SYSTEM. 如果您想要更好的控制,例如读取输出或写入输入的能力,请考虑popen()C 库中的例程。

于 2012-07-19T20:24:05.687 回答