Я разработал расширение Python с использованием C ++. Единственная функция этого модуля примерно такая:
static PyObject *TestModule_API1(PyObject *self, PyObject *args)
{
PyThreadState *_save;
_save = PyEval_SaveThread();
try
{
DoComputation1();
PyEval_RestoreThread(_save);
}
catch (const std::exception & e)
{
PyObject * py_exception = PyErr_NewException((char*)"pyhms.error", nullptr, nullptr);
PyErr_SetString(py_exception, e.what());
PyEval_RestoreThread(_save);
return nullptr;
}
Py_RETURN_NONE;
}
Всякий раз, когда я вызываю этот метод с двумя потоками Python , если метод DoComputation1()
выдает исключение, приложение вылетает. Даже помещение всего блока try в std :: mutex (блокировка в начале и разблокировка в конце блока) не решает проблему. В чем корень этой проблемы и как ее исправить?
Я занимаюсь разработкой для Windows 10 с использованием Visual Studio 2013 и Python 2.7.
Редактировать 1:
Если я перенесу строку PyEval_RestoreThread(_save);
(в блоке catch) в начало блока catch, не произойдет сбоя. Означает ли это, что во время выпуска GIL я не должен вызывать какой-либо Python API?
Редактировать 2:
Мне также нужно защитить мой метод API1 от одновременных потоков с использованием мьютекса. Должен ли я заблокировать свой мьютекс перед выпуском GIL после этого? Есть ли случай, который может привести к тупику?