使用除stdout / stderr之外的管道与子进程通信

时间:2015-02-13 17:46:43

标签: python c++ linux

这是我分叉/执行子进程并与之通信的方式(伪代码):

int cout_pipe[2];
pipe(cout_pipe);
fork();
if (child)
{
  dup2(cout_pipe[1],STDOUT_FILENO);
  execv();
}
if (parent)
{
  File* cout_file = fdopen(cout_pipe[0], "r");
}

我的问题是:

我真的不想读取子进程的stdout,我希望子进程写入除stdout之外的文件描述符。而且,我希望上面的代码从该文件描述符中读取。

子进程是用python编写的,这是C ++中的主要进程。

我想我可以改变这一行,来自:

dup2(cout_pipe[1],STDOUT_FILENO);

dup2(cout_pipe[1],MY_OWN_RANDOM_FD_NUMBER);

以我写入MY_OWN_RANDOM_FD_NUMBER而不是stdout的方式对子流程进行编码。

这是一个很好的解决方案吗?可行?我怎样才能找到一个好的MY_OWN_RANDOM_FD_NUMBER?还有更好的选择吗?

2 个答案:

答案 0 :(得分:1)

在您描述的情况下,无需复制文件描述符。对pipe()的调用已经在cout_pipe数组中创建了所需的文件描述符。

通常,子进程在执行之前简单地关闭管道的读取侧,而父进程关闭管道的写入侧。孩子将任何想要的内容写入写入端,父母可以读取或以其他方式监视管道的读取端。

如果您的问题是“子进程如何知道其执行后的fd编号,那么我会说当您在子进程中调用execv()时将其作为执行参数传递。”

类似的东西:

int   child_pipe[2];
FILE *child_file;

void forkchild(void)
{
    int  ret;
    char child_pipe_fd_str[16];

    pipe(child_pipe);  /* TODO: check return value! */

    if (0 == (ret = fork())) /* child */
    {
        close(child_pipe[0]);
        sprintf(child_pipe_fd_str, "%d", child_pipe[1]);
        execv(my_python_script, child_pipe_fd_str, NULL);
    }
    else if (-1 != ret)  /* parent */
    {
        close(cout_pipe[1]);
        child_file = fdopen(cout_pipe[0], "r");
    }
    else
    {
        perror("Fork failed!");
        abort();
    }
}

答案 1 :(得分:1)

除非你想要一个特定的fd,比如标准输出,否则dup2就没有意义了。只需将cout_pipe[1]转换为字符串,然后将其作为命令行参数传递给子项(在exec中)。在Python方面,从sys.argv中选取参数,将其转换回int,并使用os.fdopen为其获取file