【问题标题】:call gnuplot via fork and pipe and update plot通过 fork 和 pipe 调用 gnuplot 并更新绘图
【发布时间】:2015-01-31 15:54:33
【问题描述】:

我想在模拟过程中做一些实时绘图。为此,我想使用 octave 或 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 秒后停止,显示情节。

当直接在 shell 中使用 feedgnuplot 时,一切都按预期工作。 (即绘制新添加的数据,无需结束进程)

我做错了什么?我想我对 popen 的真正工作原理缺乏一些了解。

【问题讨论】:

    标签: c++ c pipe fork gnuplot


    【解决方案1】:

    首先,让我们编写一个假的 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);
    

    在开始从标准输入读取之前在 feedgnuplot 中。

    这是因为默认情况下,当标准输入对应于终端时,它是行缓冲的,而当它对应于管道时,它是完全缓冲的。上面的代码无论如何都会缓冲标准输入行,因此从终端或管道读取应该没有区别。

    【讨论】:

    • 谢谢!我找到了一种让 feedgnuplot(不是我编写的程序)按照我想要的方式运行的方法:... | feedgnuplot --stream.
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-02
    • 2013-05-28
    相关资源
    最近更新 更多