从C调用Py_Finalize()

Voo*_*Voo 10 c c++ python

这是从C++调用Python的后续内容

在程序启动时,我调用以下函数来初始化解释器:

void initPython(){
    PyEval_InitThreads();
    Py_Initialize();
    PyEval_ReleaseLock();
}
Run Code Online (Sandbox Code Playgroud)

每个线程都创建自己的数据结构并获取锁定:

PyGILState_STATE gstate;
gstate = PyGILState_Ensure();
//call python API, process results
PyGILState_Release(gstate);
Run Code Online (Sandbox Code Playgroud)

一旦你理解了GIL就会直截了当,但问题是我在调用Py_Finalize()时会遇到段错误.

void exitPython(){
    PyEval_AcquireLock();
    Py_Finalize();
}
Run Code Online (Sandbox Code Playgroud)

关于Py_Finalize()的引用是相当可疑的(或者我可能只是以错误的方式读取它)并且我不确定PyEval_AcquireLock()是否可以在有一些活动线程时获取锁定以及如果存在活动线程会发生什么当调用Py_Finalize()时.

无论如何,即使我确定所有线程都完成了他们的工作,但是只有至少创建了一个线程,我才会遇到段错误.例如,从exitPython()后面调用initPython()不会产生错误.

我可以忽略这个问题并希望操作系统知道它的作用,但我会优先考虑是否可以弄清楚发生了什么......

Voo*_*Voo 7

是的,整个部分相当可疑,但我认为我犯了错误.

我必须在初始化解释器时保存PyThreadState并在我完成时交换此状态(不知道为什么我需要一个特定的ThreadState来调用Finalize - 不应该每个状态都工作吗?)

无论如何,如果其他人遇到同样的问题的例子:

PyThreadState *mainstate;

void initPython(){
    PyEval_InitThreads();
    Py_Initialize();
    mainstate = PyThreadState_Swap(NULL);
    PyEval_ReleaseLock();
}

void exitPython(){
    PyEval_AcquireLock();
    PyThreadState_Swap(mainstate);
    Py_Finalize();
}
Run Code Online (Sandbox Code Playgroud)

唯一的问题是,我可以像其他所有线程一样获取锁,即使仍有线程工作.API没有提到当其他线程仍在工作时调用Finalize()时会发生什么.听起来像是竞争条件的完美例子.