2012-04-11 36 views
8

Tôi đang đọc tin nhắn từ ổ cắm có mã C++ và đang cố gắng vẽ nó tương tác với matplotlib, nhưng có vẻ như mã Python sẽ chặn luồng chính, bất kể tôi sử dụng show() hoặc ion()draw(). ion()draw() sẽ không chặn trong Python.Nhúng matplotlib vào C++

Bất kỳ ý tưởng nào về cách vẽ tương tác với matplotlib trong mã C++?

Ví dụ sẽ thực sự tốt.

Cảm ơn rất nhiều.

+1

Bạn đang làm gì cho đến thời điểm này không hoạt động? Làm thế nào để bạn có được dữ liệu vào python? Nó không thực sự rõ ràng những gì bạn đang thực sự cố gắng để làm. Ví dụ, bạn đang cố gắng để nguồn dữ liệu từ mã c + + và âm mưu nó bằng cách sử dụng IPython? –

+1

Ah, tôi cho rằng điều này có liên quan đến [câu hỏi khác] của bạn (http://stackoverflow.com/q/10056393/709852)? –

+0

hi, tôi đã tìm ra câu trả lời cho câu hỏi khác của mình. câu hỏi này liên quan đến việc sử dụng matplotlib trong C++, C++ code read data, và matplotlib được gọi để vẽ dữ liệu nhận được tương tác. Tôi gọi một cái gì đó như PyRun_SimpleString ("pylab nhập khẩu"); PyRun_SimpleString ("pylab.ion()"); PyRun_SimpleString ("pylab.plot (range (5))"); PyRun_SimpleString ("pylab.draw()"); nó chặn chuỗi C++ chính ngay cả khi vẽ(), không hiển thị() – bbc

Trả lời

6

Bạn cũng có thể thử tạo một chuỗi mới thực hiện cuộc gọi đến chức năng chặn , để nó không chặn IO trong vòng lặp chương trình chính của bạn. Sử dụng một mảng các đối tượng chuỗi và lặp lại để tìm một số không được sử dụng , tạo một chuỗi để thực hiện các cuộc gọi chặn và có một chuỗi khác tham gia khi chúng được hoàn thành.

Mã này là một cái tát nhanh chóng tôi đã chứng minh ý nghĩa của tôi về việc sử dụng các chủ đề để có được hành vi giả không đồng bộ cho các chức năng chặn ... Tôi chưa biên dịch hay chải kỹ nó rất đơn giản để hiển thị bạn cách thực hiện việc này.

#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; 
} 

Bằng cách này bạn có thể tiếp tục chấp nhận đầu vào trong khi vẽ đang diễn ra.

~~ Cố định để mã trên thực sự biên dịch, hãy đảm bảo thêm --pthread