我想在仿真过程中做一些实时绘图。为此,我想使用八度或gnuplot。我当前的方法是使用前端来gnuplot,feedgnuplot,这实际上非常合适。
模拟是用C ++编写的,因此我考虑了分叉(feedgnuplot的新过程)并将相关数据传递给feedgnuplot。
我的问题是输出仅在仿真后可见。
但是我想看看模拟过程中的情节更新。
这是MWE:
#define _GNU_SOURCE
#include <stdio.h>
#include <unistd.h>
int main()
{
FILE* stream = popen("feedgnuplot", "w");
for(int i = 0; i < 10; ++i)
{
fprintf(stream, "%d\n", i * i);
fflush(stream);
sleep(1);
}
}
程序在10秒后停止,显示图。
直接在外壳中使用
feedgnuplot
时,一切都会按预期进行。(也就是说,无需结束过程即可绘制新添加的数据)
我究竟做错了什么?我认为我对Popen的实际运作方式缺乏了解。
最佳答案
首先,让我们编写一个假的feedgnuplot.c:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *buf = NULL;
size_t n = 0;
while (getline (&buf, &n, stdin) != -1) {
printf ("%s", buf);
}
free (buf);
return 0;
}
这样,您的代码就可以工作,即行到达时即进行打印。
我怀疑问题出在您的feedgnuplot程序读取传入数据的方式上。您应该显示该代码的相关部分。
如果我不得不猜测,您可能需要添加
setvbuf (stdin, NULL, _IOLBF, 0);
在开始从stdin读取之前,在feedgnuplot中。
这是因为默认情况下,当stdin对应于终端时,它被行缓冲,而当它对应于管道时,它被完全缓冲。上面的代码无论如何都将stdin行缓冲,因此从终端或管道读取之间应该没有区别。