【问题标题】:C++ both input and output pipe to the external programC++ 到外部程序的输入和输出管道
【发布时间】:2019-01-30 11:47:12
【问题描述】:

我正在尝试使用一些输入调用外部程序并在程序中检索输出。

它看起来像;

(一些输入)| (外部程序)| (检索输出)

我首先考虑使用popen(),但似乎不可能,因为管道不是双向的

linux 中有没有简单的方法来处理这种事情?

我可以尝试制作一个临时文件,但如果它可以在不访问磁盘的情况下清晰地处理,那就太好了。

任何解决方案?谢谢。

【问题讨论】:

    标签: c++ process pipe system


    【解决方案1】:

    在Linux上你可以使用pipe函数:打开两个新管道,一个用于每个方向,然后使用fork创建一个子进程,之后,你通常关闭不使用的文件描述符(在父进程上读取结束,在管道的子节点上写入 end 以便父节点发送给子节点,反之亦然,然后使用 execve 或其前端之一启动您的应用程序。

    如果您dup2 管道的文件描述符到标准控制台文件句柄(STDIN_FILENO/STDOUT_FILENO;每个进程单独),您应该甚至可以使用std::cin /std::cout 用于与其他进程通信(您可能只想为子进程这样做,因为您可能希望将控制台保留在父进程中)。不过,我没有对此进行测试,所以这留给你。

    完成后,您还需要wait or waitpid 让您的子进程终止。可能类似于以下代码:

    int pipeP2C[2], pipeC2P[2];
    // (names: short for pipe for X (writing) to Y with P == parent, C == child)
    
    if(pipe(pipeP2C) != 0 || pipe(pipeC2P) != 0)
    {
        // error
        // TODO: appropriate handling
    }
    else
    {
        int pid = fork();
        if(pid < 0)
        {
            // error
            // TODO: appropriate handling
        }
        else if(pid > 0)
        {
            // parent
            // close unused ends:
            close(pipeP2C[0]); // read end
            close(pipeC2P[1]); // write end
    
            // use pipes to communicate with child...
    
            int status;
            waitpid(pid, &status, 0);
    
            // cleanup or do whatever you want to do afterwards...
        }
        else
        {
            // child
            close(pipeP2C[1]); // write end
            close(pipeC2P[0]); // read end
            dup2(pipeP2C[0], STDIN_FILENO);
            dup2(pipeC2P[1], STDOUT_FILENO);
            // you should be able now to close the two remaining
            // pipe file desciptors as well as you dup'ed them already
            // (confirmed that it is working)
            close(pipeP2C[0]);
            close(pipeC2P[1]);
    
            execve(/*...*/); // won't return - but you should now be able to
                             // use stdin/stdout to communicate with parent
        }
    }
    

    【讨论】:

    • 所以 tldr;将两个管道与分叉的子进程绑定,并将该子进程执行到目标外部程序?
    • 这两个管道名称很混乱。
    • @PavanManjunath 他们应该是“Parent writing to(2) Child”的缩写,反之亦然反之...
    猜你喜欢
    • 2014-02-04
    • 1970-01-01
    • 2012-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-21
    相关资源
    最近更新 更多