在 C++ 中嵌入 Python 在运行时崩溃

Posted

技术标签:

【中文标题】在 C++ 中嵌入 Python 在运行时崩溃【英文标题】:Embedding Python in C++ crashes during running-time 【发布时间】:2014-05-16 16:14:51 【问题描述】:

我已经在这个问题上徘徊太久了。现在我搜索了this,它工作了一段时间,但它在一个随机的地方崩溃了。我认为问题是死锁什么的。

所以请有人告诉我我做错了什么:

    我做一个全局变量:

    static int gil_init = 0; 
    

    在程序开始时,我调用Py_Initialize()。这个启动函数在一个会话中被多次调用,但由于Py_Initialize() 是一个非操作,如果 Python 已经初始化,我认为这里没有问题。

    从三个函数中,我对 Python/C API 函数 -py_embed(...) 进行了大量调用(一次只有一个调用)。下一个代码出现在从每个线程调用的 py_embed() 函数中:

    if (!gil_init) 
        gil_init = 1;
        PyEval_InitThreads();
        PyEval_SaveThread();
    
    state = PyGILState_Ensure();
    // Call Python/C API functions...
    //pValue= PyObject_CallObject(pFunc, pArgs2);  Crash is always given here
    PyGILState_Release(state);
    

哦,崩溃发生在其中一个函数中,但不是我第一次调用它,这很奇怪。这就是为什么我在运行时随机说它的原因。

理论上,根据C Api 的参考手册,它应该可以工作。我做错了什么?

编辑:我不打电话给Py_Finalize(),因为我有this problem

【问题讨论】:

【参考方案1】:

看看this post,它帮助我解决了我遇到的一些线程问题。特别是这部分:

不过,我发现这可能会导致间歇性 死锁。似乎每个 PyThreadState 使用的 PyGILState_Ensure() 不唯一,导致多线程 试图恢复相同的PyThreadState,导致死锁。 这很简单,可以通过保证每个线程都有 它自己的PyThreadState。部分解决方案如下:

 // Once in each thread
 m_state = PyThreadState_New(m_interpreterState);
 PyEval_RestoreThread(m_state);

 // Perform some Python actions here

 // Release Python GIL
 PyEval_SaveThread();

【讨论】:

Ty 评论。不幸的是,这不起作用。我设置了多个断点,我注意到当它到达 m_state = PyThreadState_New(m_interpreterState); 时它会停止......所以甚至没有到达 python 脚本【参考方案2】:

我想我解决了(不能肯定,但直到现在它还没有崩溃)。

问题是我取消了一些借来的引用。我注意到这一点是因为某些对象的引用计数是 2 或 3。

【讨论】:

以上是关于在 C++ 中嵌入 Python 在运行时崩溃的主要内容,如果未能解决你的问题,请参考以下文章

在 C++ 中嵌入 python

在 C++ 套接字编程中嵌入 Python

从 C++ 停止嵌入式 Python 提示符

嵌入式python问题

传递元组嵌入式 Python

在嵌入式 Python C++ 应用程序中导入 Numpy