1

经过几天的搜索,是时候问了。环境是 Ubuntu 12.04/Gnome。

我正在 ubuntu 机器上开发一些嵌入式代码,并在移植到嵌入式处理器之前在该环境中尽可能多地进行测试。当前例程是实时快速傅立叶变换,我想使用 gnuplot 来显示结果。所以我希望我的测试代码和 gnuplot 同时在前台运行并通过管道进行通信。

我做了通常的 popen() 调用,除了一件事外,它有效。孩子的标准输入(gnuplot)仍然连接到控制台。它与父进程发生争用。父进程需要接收击键来修改其行为。有时父母得到击键,有时 gnuplot 得到。

所以我尝试了 fork/exec 路径。具体来说

        pid_t pg = tcgetpgrp(1);    // get process group associated with stdout
        cerr << "pid_t pg = " << pg << endl;
        cerr << "process pid is " << getpid() << endl;

        if (pipe(pipefd) == -1) {// open the pipe
            cerr << "pipe failure" << endl;
            exit(3);
        } // if pipe

        cpid = fork();
        if (cpid == -1) {
            cerr << "fork failure" << endl;
            exit(1);
        }

        if (cpid == 0)  {   // this is the child process

            if (tcsetpgrp(1, pg) == -1) {           // this should set the process associated with stdin (gnuplot) with the
                cerr << "tcsetgrp failed" << endl;  // foreground terminal.
                exit(7);
            }

            close(pipefd[1]);    // close child's writing handle

            if (pipefd[0] != STDIN_FILENO) {    // this changes the file descripter of stdin back to 0
                if ( dup2(pipefd[0], STDIN_FILENO) != STDIN_FILENO) {
                    cerr << "dup2 error on stdin" << endl;
                    exit(6);
                }
            }


            if (execl("/usr/bin/gnuplot", "gnuplot", "-background", "white", "-raise", (char *) NULL)) {                
                cerr << "execl failed" << endl;
                exit(2);
            }  else // if exec
                close(pipefd[0]);   // close parent's reading handle

        } // if cpid


        // back in parent process

正如我所期望的那样,这会触发 gnuplot。我可以看到 gnuplot 像往常一样消耗了一个内核的所有资源。问题是屏幕上没有图表出现。

所以我的问题是,我如何启动一个子进程,将它与控制台完全分离,这样它就不会得到任何击键并让 gnuplot 的输出显示?

4

0 回答 0