2012-04-11 28 views
8

に私はC++のコードでソケットからのメッセージを読んでいますとmatplotlibで対話的にそれをプロットしようとしていますが、Pythonのコードはメインスレッド、私はshow()またはion()draw()を使用するに関係なくブロックされますようです。 ion()draw()はPythonではブロックされません。埋め込みmatplotlibのC++

C++コードでmatplotlibと対話的にプロットする方法はありますか?

例は本当に良いでしょう。

ありがとうございます。

+1

これまで動作していないことは何ですか?どのようにしてデータをPythonに変換しますか?あなたが実際にやろうとしていることは本当に明確ではありません。たとえば、C++コードからデータを取得し、IPythonを使用してプロットしようとしていますか? –

+1

ああ、私はあなたの[その他の質問](http://stackoverflow.com/q/10056393/709852)と関係があると推測していますか? –

+0

こんにちは、私は他の質問に答えました。この質問は、C++でのmatplotlibの使用、C++コードのデータの読み込み、matplotlibを呼び出してインタラクティブに受け取ったデータをプロットすることに関するものです。私は のようなものを呼び出します。PyRun_SimpleString( "import pylab"); PyRun_SimpleString( "pylab.ion()"); PyRun_SimpleString( "pylab.plot(range(5))"); PyRun_SimpleString( "pylab.draw()"); show()でなくdraw()であってもメインのC++スレッドをブロックします – bbc

答えて

6

ブロッキング関数の呼び出しを行う新しいスレッドを作成して、メインプログラム ループのIOをブロックしないようにすることもできます。スレッドオブジェクトの配列を使用してループスルーを使用して未使用の を見つけ、スレッドを作成してブロック呼び出しを行い、完了時に他のスレッド を結合させます。

このコードは、私がおよそ 機能を阻止するための疑似非同期動作を取得するために、スレッドを使って何を意味するかを証明するためにやった迅速平手打ち、一緒に... である私は非常によく、それをコンパイルまたはその上にとかしていない、それは単にですこれを達成する方法を に表示してください。

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

この方法では、描画が行われている間も入力を受け入れ続けることができます。

~~上記のコードが実際にコンパイルされているので、-lpthreadを必ず追加してください。