调用 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

AWS Redshift Vacuum 返回错误:断言

Direct2d CreateBitmapfromWICBitmap 在 ATL 中给出断言错误

OpenCV 错误:调用 detectMultiScale 时断言失败

什么时候用异常,什么时候用断言?