经过几天的搜索,是时候问了。环境是 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 的输出显示?