Ésta es una continuación de Call Python from C++Calling Py_Finalize() de C
Al inicio de la Programm que llamo la siguiente función para inicializar el intérprete:
void initPython(){
PyEval_InitThreads();
Py_Initialize();
PyEval_ReleaseLock();
}
Cada hilo crea su propia estructura de datos y adquiere la cerradura con:
PyGILState_STATE gstate;
gstate = PyGILState_Ensure();
//call python API, process results
PyGILState_Release(gstate);
Más bien sencillo una vez entendido el GIL, pero el problema es que me sale un error de segmentación cuando se llama a Py_Finalize().
void exitPython(){
PyEval_AcquireLock();
Py_Finalize();
}
La referencia es bastante dudosa sobre Py_Finalize() (o tal vez sólo estoy leyendo el camino equivocado) y no estoy seguro de si PyEval_AcquireLock() puede adquirir el bloqueo si hay algunos hilos activos y qué sucede si hay subprocesos activos cuando se llama a Py_Finalize().
De todos modos, obtengo un segfault incluso si estoy seguro de que todos los hilos han terminado su trabajo, pero solo si se creó al menos uno. P.ej. llamando a initPython() seguido de exitPython() no crea ningún error.
tan sólo pudiera ignorar el problema y esperar que el sistema operativo sabe lo que hace, pero yo prefere si podía averiguar lo que está pasando ..
He comentado todo pero PyGILState_Ensure() y Release() y el error todavía se produce. Si los comento también, no hay ningún problema. – Voo
En ese caso, supongo que hay algo sobre la administración de subprocesos que no se está haciendo correctamente. Desafortunadamente, la página relevante de C API con todas las funciones de subprocesos no es obvia en cuanto a cuál de esas llamadas necesita. – Kylotan
Las "llamadas que necesita" la mayor parte del tiempo son 'Py_BEGIN_ALLOW_THREADS' y su contraparte. Esas son, a su vez, macros que usan 'PyEval_SaveThread()' y su contraparte. Entonces, si estuviera escribiendo algo como OP, seguiría ese ejemplo. – Kevin