在 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 在运行时崩溃的主要内容,如果未能解决你的问题,请参考以下文章