C 分叉管道子进程

C 分叉管道子进程,c,exec,fork,C,Exec,Fork,分叉管道内衬子流程的最佳技术是什么 我当前的程序需要运行另一个进程,实际上是由管道链接的两个命令。如果命令失败或成功,我不需要知道命令的输出,所以我使用fork/exec 命令行上的等效项是 /path/to/A arg1 arg2 | /path/to/B argB1 | /path/to/C 注意:使用脚本是不实际的,因为它可能会在将来更改a/B/C 我想到的两种技术是: 递归fork。连接下一个fork中可用于子级的父级(输入到其父级)输出 在顶层创建所有管道。 然后使用一个循环来分叉

分叉管道内衬子流程的最佳技术是什么

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

命令行上的等效项是

 /path/to/A arg1 arg2 | /path/to/B argB1 | /path/to/C
注意:使用脚本是不实际的,因为它可能会在将来更改a/B/C

我想到的两种技术是:

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

  • 在顶层创建所有管道。
    然后使用一个循环来分叉所有子级,然后可以适当地连接管道


  • 如果您在unix上,一个简单的
    系统(“/path/to/a arg1 arg2 |/path/to/B argB1 |/path/to/C”)
    将执行您想要的操作。它以传递给系统的形式调用shell。如果您想要更好的控制,例如读取输出或写入输入的能力,请考虑C库中的<代码> PONEN()/Cuff>例程。< /P> < P>不要递归递归。让B成为a的子流程不是一个好主意。例如,如果B调用
    setsid
    以在其自己的会话中运行,则它将使用不相关的A。如果B死了,A会得到一个孩子,而不是你。特别是,您将无法获得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 */
    
    char*可执行文件[n];
    字符*args[n];
    内部管道[2*n+2];/*我读书的孩子*/
    int child_pids[n];
    int ret/*省略错误检查;如果ret变为负值,则中止*/
    ret=管道(管道);
    对于(i=0;i
    后者是Shell所做的,大概有一个很好的理由。@OliCharlesworth:你有参考资料吗?或者最好是一个指向示例代码的链接,这样我就不会再发明轮子了。如果你在Linux上工作,你可以通过运行
    pstree
    来推断这一点,它显示了所有进程的父子关系。我真的不想使用system()或popen()。我使用的一些论点有点复杂,引用和逃避引用会变得非常混乱。我想使用execvp()确保参数正确地传递给子进程。我向您保证,正确的命令转义过程比创建工作管道链简单。或者,也可以将获取奇怪参数的命令包装在脚本中,或者将通过文件获取其参数的变体版本中,等等。。。获取所有管道()/dup()/fork()/exec()逻辑正确的过程是复杂且容易出错的。正如Oli在上面指出的,shell已经为您完成了这项工作。