2012-04-11 6 views
8

estoy leyendo un mensaje de una toma de corriente con código C++ y estoy tratando de trazar de forma interactiva con matplotlib, pero parece que el código Python bloqueará el hilo principal, no importa lo uso show() o ion() y draw(). ion() y draw() no se bloquearán en Python.Incorporación matplotlib en C++

¿Alguna idea de cómo trazar interactivamente con matplotlib en código C++?

Un ejemplo sería realmente bueno.

Muchas gracias.

+1

¿Qué haces tan lejos que no funciona? ¿Cómo se obtienen los datos en python? No está claro qué intentas hacer en realidad. Por ejemplo, ¿está tratando de obtener datos del código de C++ y trazarlos usando IPython? –

+1

Ah, supongo que esto tiene algo que ver con su [otra pregunta] (http://stackoverflow.com/q/10056393/709852)? –

+0

hola, calculé la respuesta a mi otra pregunta. esta pregunta es sobre el uso de matplotlib en C++, datos de lectura de código de C++, y se llama a matplotlib para trazar los datos recibidos de forma interactiva. Llamo a algo como PyRun_SimpleString ("import pylab"); PyRun_SimpleString ("pylab.ion()"); PyRun_SimpleString ("pylab.plot (rango (5))"); PyRun_SimpleString ("pylab.draw()"); bloquea el hilo principal de C++ incluso con draw(), not show() – bbc

Respuesta

6

También puede intentar crear un nuevo hilo que haga la llamada a la función de bloqueo , de modo que no bloquee IO en su ciclo del programa principal. Utilice una matriz de objetos de subprocesos y recorra para encontrar un no utilizado, cree un subproceso para hacer las llamadas de bloqueo y tenga otro subproceso que los una cuando se completen.

Este código es una bofetada-juntos rápida que hice para demostrar lo que quiero decir sobre utilizando hilos para conseguir el comportamiento seudo asíncrono para funciones de bloqueo ... no he compilado o peinados sobre ella muy bien, es simplemente para mostrar cómo lograr esto.

#include <pthread.h> 
#include <sys/types.h> 
#include <string> 
#include <memory.h> 
#include <malloc.h> 
#define MAX_THREADS 256 // Make this as low as possible! 
using namespace std; 
pthread_t PTHREAD_NULL; 
typedef string someTypeOrStruct; 
class MyClass 
{ 
    typedef struct 
    { 
     int id; 
     MyClass *obj; 
     someTypeOrStruct input; 
    } thread_data; 

    void draw(); //Undefined in this example 
    bool getInput(someTypeOrStruct *); //Undefined in this example 
    int AsyncDraw(MyClass * obj, someTypeOrStruct &input); 
    static void * Joiner(MyClass * obj); 
    static void * DoDraw(thread_data *arg); 
    pthread_t thread[MAX_THREADS], JoinThread; 
    bool threadRunning[MAX_THREADS], StopJoinThread; 

    bool exitRequested; 
public: 
    void Main(); 
}; 

bool MyClass::getInput(someTypeOrStruct *input) 
{ 
} 

void MyClass::Main() 
{ 
    exitRequested = false; 
    pthread_create(&JoinThread, NULL, (void *(*)(void *))MyClass::Joiner, this); 

    while(!exitRequested) 
    { 
     someTypeOrStruct tmpinput; 
     if(getInput(&tmpinput)) 
      AsyncDraw(this, tmpinput); 
    } 

    if(JoinThread != PTHREAD_NULL) 
    { 
     StopJoinThread = true; 
     pthread_join(JoinThread, NULL); 
    } 
} 

void *MyClass::DoDraw(thread_data *arg) 
{ 
    if(arg == NULL) return NULL; 
    thread_data *data = (thread_data *) arg; 
    data->obj->threadRunning[data->id] = true; 
    // -> Do your draw here <- // 
    free(arg); 
    data->obj->threadRunning[data->id] = false; // Let the joinThread know we are done with this handle... 
} 

int MyClass::AsyncDraw(MyClass *obj, someTypeOrStruct &input) 
{ 
    int timeout = 10; // Adjust higher to make it try harder... 
    while(timeout) 
    { 
     for(int i = 0; i < MAX_THREADS; i++) 
     { 
      if(thread[i] == PTHREAD_NULL) 
      { 
       thread_data *data = (thread_data *)malloc(sizeof(thread_data)); 
       if(data) 
       { 
        data->id = i; 
        data->obj = this; 
        data->input = input; 

        pthread_create(&(thread[i]), NULL,(void* (*)(void*))MyClass::DoDraw, (void *)&data); 
        return 1; 
       } 
       return 0; 
      } 
     } 
     timeout--; 
    } 
} 

void *MyClass::Joiner(MyClass * obj) 
{ 
    obj->StopJoinThread = false; 
    while(!obj->StopJoinThread) 
    { 
     for(int i = 0; i < MAX_THREADS; i++) 
      if(!obj->threadRunning[i] && obj->thread[i] != PTHREAD_NULL) 
      { 
       pthread_join(obj->thread[i], NULL); 
       obj->thread[i] = PTHREAD_NULL; 
      } 
    } 
} 

int main(int argc, char **argv) 
{ 
    MyClass base; 
    base.Main(); 
    return 0; 
} 

De esta manera puede seguir aceptando la entrada mientras se produce el sorteo.

~~ fijo, por lo que el código anterior se compila en realidad, asegúrese de agregar -lpthread

Cuestiones relacionadas