调用 Py_Finalize 返回断言错误
Posted
技术标签:
【中文标题】调用 Py_Finalize 返回断言错误【英文标题】:Calling Py_Finalize returns assertation error 【发布时间】:2018-07-10 14:13:08 【问题描述】:我正在尝试从 c++ 调用 python 代码,并且我正在使用以下 QThread
类。
myclassName::myclassName()
Py_Initialize();
myclassName::~myclassName()
Py_Finalize();
void myclassName::cpp_wrapper(string out1, string out2)
ThreadState = PyEval_SaveThread();
GILState = PyGILState_Ensure();
Py_DECREF(PyImport_ImportModule("threading"));
PyObject *moduleMain = PyImport_ImportModule("__main__");
PyRun_SimpleString(
"def wrapper(arg1, arg2) : \n"\
" import sklearn \n"\
" print(arg1, arg2) \n"\
);
PyObject *func = PyObject_GetAttrString(moduleMain, "wrapper");
PyObject *args = PyTuple_Pack(2, PyUnicode_FromString(out1.c_str()), PyUnicode_FromString(out1.c_str()));
Py_DECREF(moduleMain);
Py_DECREF(func);
Py_DECREF(args);
PyGILState_Release(GILState);
PyEval_RestoreThread(ThreadState);
void myclassName::run()
algorithm_wrapper("Hello1", "Hello2");
//here a sginal is emmited to the main thread function to delete myclassName* item.
int main()
myclassName* item = new myclassName();
item->run();
执行很好(感谢@Thomas 在上一篇文章中)但是当调用Py_Finalize
时返回以下错误。 Py_Finalize
在执行 python 代码时调用,并向主线程中的插槽发出信号以删除类对象。我还尝试在主线程中初始化和完成 python(再次通过发送信号),但返回了相同的错误。
Exception ignored in: <module 'threading' from 'C:\\Users\\username\\AppData\\Local\\Continuum\\Anaconda3\\Lib\\threading.py'>
Traceback (most recent call last):
File "C:\Users\username\AppData\Local\Continuum\Anaconda3\Lib\threading.py", line 1289, in _shutdown
assert tlock.locked()
你能提供一些帮助吗?
编辑:在@Abid Rahman K 的请求之后。
.h 文件
class myclassName : public QThread
Q_OBJECT
public:
myclassName();
~myclassName();
protected:
void run();
private:
QMutex mutex_Python;
;
.cpp 文件
myclassName::myclassName():
mutex_Python(QMutex::Recursive)
Py_Initialize();
myclassName::~myclassName()
Py_Finalize();
void myclassName::cpp_wrapper(string out1, string out2)
//ThreadState = PyEval_SaveThread();
//GILState = PyGILState_Ensure();
mutex_Python.lock();
Py_DECREF(PyImport_ImportModule("threading"));
PyObject *moduleMain = PyImport_ImportModule("__main__");
PyRun_SimpleString(
"def wrapper(arg1, arg2) : \n"\
" import sklearn \n"\
" print(arg1, arg2) \n"\
);
PyObject *func = PyObject_GetAttrString(moduleMain, "wrapper");
PyObject *args = PyTuple_Pack(2, PyUnicode_FromString(out1.c_str()), PyUnicode_FromString(out1.c_str()));
Py_DECREF(moduleMain);
Py_DECREF(func);
Py_DECREF(args);
mutex_Python.unlock();
//PyGILState_Release(GILState);
//PyEval_RestoreThread(ThreadState);
void myclassName::run()
algorithm_wrapper("Hello1", "Hello2");
//here a sginal is emmited to the main thread function to delete myclassName* item.
int main()
myclassName* item = new myclassName();
item->run();
【问题讨论】:
你能解决这个问题吗?怎么样? @AbidRahmanK 我根据我使用的代码在我的帖子中进行了编辑。老实说,我不记得太多。我希望这会有所帮助。 【参考方案1】:如 Python 官网关于 Py_Finalize 所述:
“Bugs and Caveats:模块和模块中对象的销毁是随机顺序进行的;这可能会导致析构函数(del()方法)在依赖其他对象(甚至函数)时失败) 或模块。由 Python 加载的动态加载的扩展模块不会被卸载。Python 解释器分配的少量内存可能不会被释放(如果发现泄漏,请报告)。对象之间的循环引用占用的内存不会已释放。扩展模块分配的某些内存可能不会被释放。如果多次调用其初始化例程,某些扩展可能无法正常工作;如果应用程序多次调用 Py_Initialize() 和 Py_Finalize(),则可能会发生这种情况。"
因此,您在调用 Py_Finalize 之前手动完成广告处置资源和流程
【讨论】:
以上是关于调用 Py_Finalize 返回断言错误的主要内容,如果未能解决你的问题,请参考以下文章
嵌入式 Python 应用程序中 Py_Finalize 期间的致命错误
Py_Initialize 和 Py_finalize 和 MatPlotlib
Direct2d CreateBitmapfromWICBitmap 在 ATL 中给出断言错误