【问题标题】:Alternative for popen pipe to execute program and read the output替代 popen 管道执行程序并读取输出
【发布时间】:2012-06-11 17:03:52
【问题描述】:

请建议popen() 执行shell 命令然后读取输出的好方法。

编辑: 替代方案必须没有fork() 调用。因为我的服务器已经占用了太多内存。然后ffmpeg 还需要增加内存和进程大小!我每次都将问题发送到fork() 到内存权重服务器。

【问题讨论】:

    标签: c++ popen


    【解决方案1】:

    如果你担心fork时复制父进程的内存,那么你需要使用vfork()——一个特殊版本的“fork”,它不会复制父进程的内存,但要求被fork的进程立即问题execve()

    【讨论】:

    • 能否请您添加示例如何使用它作为 popen() 的替代品?我当前的 popen 代码在这里 stackoverflow.com/questions/10962044/… 。奇怪的是,popen 默认不使用 vfork()....
    • "vfork() 函数也会先执行子进程,并在子进程终止时恢复父进程。" -- 我的服务器和用户会在ffmpeg 执行时等待10 分钟? :) 陷阱
    • @abrahab:请仔细阅读手册页。孩子拨打execve时,家长会立即恢复。
    • 谢谢,知道了!它很有用,似乎可以很好地替代我的宽度内存和性能敏感服务器上的system 调用,但仍然无法理解如何调用vforkexecve 以从execve 获取输出到父级。跨度>
    【解决方案2】:

    这就是我在学校的教学方式:

    int main(int argc, char *argv[]) {
    
        int pipefd[2];
        pid_t cpid;
        char buf;
    
    
        if (pipe(pipefd) == -1) {
            perror("pipe");
            exit(EXIT_FAILURE);
        }
    
        cpid = fork();
        if (cpid == -1) {
            perror("fork");
            exit(EXIT_FAILURE);
        }
    
        if (cpid == 0) {
            /* Child reads from pipe */
            close(pipefd[1]);
    
            //make the standard input to be the read end
            pipefd[0] = dup2(pipefd[0], STDIN_FILENO);
    
            system("more");
    
            write(STDOUT_FILENO, "\n", 1);
            close(pipefd[0]);
    
    
        } else {
    
            /* Parent writes argv[1] to pipe */
            close(pipefd[0]);
            /* Close unused read end */
    
            pipefd[1] = dup2(pipefd[1], STDOUT_FILENO);
    
            system("ps aux");
            /* Wait for child */
            wait(NULL);
            exit(EXIT_SUCCESS);
        }
    
        return 0;
    }
    

    这会产生两个进程,一个执行“ps aux”并将输出提供给另一个运行“more”的进程。

    【讨论】:

    • 在这种情况下你会被卡住,因为popen 只是总结了通常的fork/exec 成语。
    • @dmckee 宾果游戏!也许——也许!因为它在一个接一个之后给出 2-3 次调用 popen 并且通常服务器是 200-300 mbs。好的。如何解决这个问题?我应该在没有 fork() 的情况下使用该 exec 吗?是的,看来我必须找到 popen() 的替代方法
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多