Я внедряю интерпретатор python в многопоточное приложение C, и я немного запутался в отношении того, какие API-интерфейсы я должен использовать для обеспечения безопасности потоков.
Из того, что я собрал, при встраивании python, до того, как вызывать любой другой вызов API Python C, перед вложением должен позаботиться о блокировке GIL. Это делается с помощью следующих функций:
gstate = PyGILState_Ensure();
// do some python api calls, run python scripts
PyGILState_Release(gstate);
Но этого, по-видимому, недостаточно. У меня все еще были случайные сбои, так как он, похоже, не предусматривает взаимного исключения для API-интерфейсов Python.
После чтения еще нескольких документов я также добавил:
PyEval_InitThreads();
сразу после вызова Py_IsInitialized()
, но там, где возникает запутанная часть. Документы утверждают, что эта функция:
Инициализировать и получить глобальную блокировку интерпретатора
Это говорит о том, что когда эта функция возвращается, предполагается, что GIL заблокирован и должен быть разблокирован каким-то образом. но на практике это, как представляется, не требуется. Благодаря этой линии моя многопоточная работа отлично работала, и взаимное исключение поддерживалось функциями PyGILState_Ensure/Release
.
Когда я попытался добавить PyEval_ReleaseLock()
после PyEval_ReleaseLock()
, приложение быстро блокировалось при последующем вызове PyImport_ExecCodeModule()
.
Так что мне здесь не хватает?