Python yorumlayıcısını çok iş parçacıklı bir C uygulamasına yerleştiriyorum ve iş parçacığı güvenliğini sağlamak için hangi API'ları kullanmam gerektiği konusunda kafam karıştı. piton gömerken Anlamıştım kadarıylaPython'u çok iş parçacıklı C uygulamasında gömme
, başka herhangi bir Python C API çağrısını çağırmadan önce GiL kilit bakmak yerleştirerrtarafmdan kalmıştır. Bu durum, bu işlevlerle yapılabilir:
gstate = PyGILState_Ensure();
// do some python api calls, run python scripts
PyGILState_Release(gstate);
Ama bu tek başına yeterli görünmüyor. Python API'ları için karşılıklı dışlama sağlamayacak gibi göründüğü için hala rastgele çökmelerim var. Sağ Py_IsInitialized()
çağrısının
PyEval_InitThreads();
ama kafa karıştırıcı kısmı devreye giriyor:
Ben de eklendi biraz daha docs okuduktan sonra.başlat ve küresel tercüman
Bu, bu işlevin döndürdüğü GIL farz edildiğinde kilitlenmesini ve bir şekilde kilidi gerektiğini önermektedir kilidi kazanmak: docs bu işlev belirtmektedirler. ama pratikte bu gerekli görünmüyor. Bu satır ile benim multithreaded çalıştım mükemmel ve karşılıklı dışlama PyGILState_Ensure/Release
işlevleri tarafından korunur.
PyEval_ReleaseLock()
'u PyEval_ReleaseLock()
ekledikten sonra uygulama PyImport_ExecCodeModule()
sonraki aramaya hızlı bir şekilde kilitlendi.
Burada neyi özlüyorum?
Bu yanlış ve potansiyel olarak zararlı: 'PyEval_SaveThread' her zaman PyEval_RestoreThread ile bağlantılı olmalıdır. [Başka yerlerde açıklandığı gibi] (http://stackoverflow.com/a/15471525/1600898), kilidi başlattıktan sonra serbest bırakmaya çalışmamalısınız; Onu düzenli çalışmasının bir parçası olarak bırakmak için Python'a bırakın. – user4815162342
Tüm çağrıları bir _Block_ _Allow_ bloğunda python'a koyarsanız neden zararlı olduğunu anlamıyorum. Öte yandan, eğer PyEval_SaveThread(); 'i çağırmazsanız, ana parçanız diğer iş parçacıklarının Python'a erişimini engelleyecektir. Başka bir deyişle PyGILState_Ensure() 'deadlocks. – khkarens
Her ikisi de Python'u gömmek ve bir uzantı modülüne çağırmak için çalışan tek şey. –