【问题标题】:Embedding matplotlib in C++在 C++ 中嵌入 matplotlib
【发布时间】:2012-04-23 23:31:18
【问题描述】:

我正在使用 C++ 代码从套接字读取消息,并尝试使用 matplotlib 交互地绘制它,但似乎 Python 代码会阻塞主线程,无论我使用 show()ion() 和 @ 987654326@。 ion()draw() 在 Python 中不会阻塞。

知道如何在 C++ 代码中与 matplotlib 交互绘图吗?

举个例子就好了。

非常感谢。

【问题讨论】:

  • 到目前为止,您在做什么但不起作用?你如何将数据输入python?目前还不清楚您实际上要做什么。例如,您是否尝试从 c++ 代码中获取数据并使用 IPython 绘制它?
  • 啊,我想这和你的other question有关?
  • 嗨,我想出了另一个问题的答案。这个问题是关于在 c++ 中使用 matplotlib,c++ 代码读取数据,并调用 matplotlib 来绘制交互式接收的数据。我称之为 PyRun_SimpleString("import pylab"); PyRun_SimpleString("pylab.ion()"); PyRun_SimpleString("pylab.plot(range(5))"); PyRun_SimpleString("pylab.draw()");即使使用draw(),它也会阻塞主c ++线程,而不是show()
  • 所以这些调用是在一个新线程中进行的?听起来您与global interpreter lock 的互动很不利。不幸的是,我对 The Very High Level Layer 如何与 GIL 交互一无所知。我怀疑它会抓住它并在通话返回时将其归还。它回来了吗?如果你只是使用 python 进行绘图,为什么不将数据通过管道传输到 python 进程?
  • 好的,据我了解,您有一些想要使用的 C++ 库,但是从 python 中绘制数据?你能不能不走另一条路——从 Python 中调用 C++ 库?这更容易做到,并且被更广泛地理解。

标签: c++ python matplotlib


【解决方案1】:

您也可以尝试创建一个新线程来调用 阻塞函数,这样它就不会阻塞主程序中的 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

【讨论】:

    猜你喜欢
    • 2017-11-23
    • 1970-01-01
    • 1970-01-01
    • 2018-06-14
    • 2019-04-08
    • 2011-05-03
    • 2014-10-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多