Это следовать до Call Python from C++Вызов Py_Finalize() из C
При запуске программе я называю следующую функцию для инициализации интерпретатора:
void initPython(){
PyEval_InitThreads();
Py_Initialize();
PyEval_ReleaseLock();
}
Каждый поток создает свою собственную структуру данных и получает блокировку с:
PyGILState_STATE gstate;
gstate = PyGILState_Ensure();
//call python API, process results
PyGILState_Release(gstate);
Скорее прямо вперед, как только вы поняли GIL, но проблема в том, что я получаю Segfault при вызове Py_Finalize().
void exitPython(){
PyEval_AcquireLock();
Py_Finalize();
}
Ссылка весьма сомнительна о Py_Finalize() (или, может быть, я просто читал это неправильный путь), и я не уверен, что если PyEval_AcquireLock() может получить блокировку, если есть некоторые активные потоки и что происходит, если есть активные потоки, когда вызывается Py_Finalize().
В любом случае, я получаю segfault, даже если я уверен, что все потоки завершили свою работу, но только если был создан хотя бы один. Например. вызов initPython(), который следует из exitPython(), не создает ошибок.
я мог бы просто игнорировать эту проблему и надеюсь, что операционная система знает, что он делает, но я предпочитаю, если бы я мог понять, что происходит ..
Я прокомментировал все, но PyGILState_Ensure() и Release(), и ошибка все еще происходит. Если я их прокомментирую, это не проблема .. – Voo
В этом случае я предполагаю, что есть что-то в управлении потоками, которое не выполняется должным образом. К сожалению, соответствующая страница C API со всеми функциями потока на ней далеко не очевидна относительно того, какой из этих вызовов вам нужен. – Kylotan
«Звонки вам нужны» большую часть времени - «Py_BEGIN_ALLOW_THREADS» и его коллега. Это, в свою очередь, макросы, которые используют 'PyEval_SaveThread()' и его аналог. Поэтому, если бы я писал что-то вроде OP, я бы следовал этому примеру. – Kevin