2015-01-31 4 views
0

Я хочу сделать некоторые графики в реальном времени во время моделирования. Для этого я хотел бы использовать октаву или gnuplot. Мой текущий подход заключается в использовании интерфейса для gnuplot, feedgnuplot, который очень хорошо подходит.вызов gnuplot через fork and pipe и график обновления

Моделирование написано на C++, поэтому я подумал о forking (новый процесс для 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 secons, показывающий сюжет.

При использовании feedgnuplot непосредственно в оболочке все работает должным образом. (То есть, новые данные выводятся без необходимости завершения процесса)

Что я делаю неправильно? Я думаю, что мне не хватает понимания того, как работает Popen.

ответ

0

Во-первых, давайте напишем поддельный 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, прежде чем начать читать из стандартного ввода.

Это потому, что по умолчанию, когда stdin соответствует терминалу, он буферизируется по строке, тогда как когда он соответствует каналу, он полностью буферизуется. Вышеприведенный код делает stdin-строку буферной независимо от того, что не должно быть никакой разницы между чтением с терминала или трубы.

+0

Спасибо! Я нашел способ сделать feedgnuplot (программа, не написанная мной) вести себя так, как я хочу: '... | feedgnuplot --stream'. – pschulz