Встраивание python в многопоточное приложение на C

Я встраиваю интерпретатор python в многопоточное приложение C и немного не понимаю, какие API следует использовать для обеспечения безопасности потоков.

Из того, что я понял, при встраивании python интегратор должен позаботиться о блокировке GIL перед вызовом любого другого вызова Python C API. Это делается с помощью следующих функций:

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().

Так что же я здесь упускаю?

17
задан Amro 21 August 2012 в 00:43
поделиться