我在多線程C應用程序中嵌入python解釋器,我對使用哪些API來確保線程安全性有些困惑。在多線程C應用程序中嵌入python
從我所收集的內容來看,在嵌入python時,需要在調用任何其他Python C API調用之前由嵌入器負責照顧GIL鎖。這是用這些功能完成的:
gstate = PyGILState_Ensure();
// do some python api calls, run python scripts
PyGILState_Release(gstate);
但是,這似乎是不夠的。我仍然遇到隨機崩潰,因爲它似乎沒有爲Python API提供互斥。
閱讀一些文檔我還添加了後:
PyEval_InitThreads();
調用
Py_IsInitialized()
之後
但是這也正是混淆的部分來了。該文檔指出此函數:
初始化和獲取全局解釋鎖
這表明,當這個函數返回時,GIL應該被鎖定,應該得到某種解鎖。但實際上這似乎並不需要。有了這條線,我的多線程工作就完美了,互斥也由PyGILState_Ensure/Release
函數維護。
當我嘗試在PyEval_ReleaseLock()
之後添加PyEval_ReleaseLock()
後,該應用程序在後續調用PyImport_ExecCodeModule()
時很快就鎖定。
那我在這裏失蹤?
這是錯誤的,可能有害:'PyEval_SaveThread'應該總是和'PyEval_RestoreThread'一起使用。如[其他地方解釋](http://stackoverflow.com/a/15471525/1600898),初始化後不應嘗試釋放鎖;只需將它留給Python即可將其作爲其常規工作的一部分發布。 – user4815162342
我不明白爲什麼它是有害的,如果你把所有的調用python在_Block_ _Allow_塊。另一方面,如果你不調用'PyEval_SaveThread();'那麼你的主線程將阻止其他線程訪問Python。換句話說'PyGILState_Ensure()'死鎖。 – khkarens
這是嵌入Python和調用擴展模塊的唯一工具。 –