Incruste el intérprete de python en una aplicación C multiproceso y estoy un poco confundido con respecto a las API que debo usar para garantizar la seguridad de los hilos.Incrustar python en la aplicación de C multiproceso
De lo que he reunido, al incrustar pitón que está hasta la embedder para cuidar de la cerradura GIL antes de llamar a cualquier otra llamada a la API de Python C. Esto se hace con estas funciones:
gstate = PyGILState_Ensure();
// do some python api calls, run python scripts
PyGILState_Release(gstate);
Pero esto por sí solo no parece ser suficiente. Todavía tengo bloqueos aleatorios ya que no parece proporcionar exclusión mutua para las API de Python.
Después de leer algunos documentos más También he añadido:
PyEval_InitThreads();
justo después de la llamada a Py_IsInitialized()
pero ahí es donde la parte confusa viene. Los documentos indican que esta función:
inicializar y adquieren bloquear el intérprete mundial
Esto sugiere que cuando se devuelve esta función, el GIL se supone que es bloqueado y debe ser desbloqueado de alguna manera. pero en la práctica esto no parece ser necesario. Con esta línea, mi multiproceso funcionó perfectamente y la exclusión mutua se mantuvo gracias a las funciones PyGILState_Ensure/Release
.
Cuando intenté agregar PyEval_ReleaseLock()
después de PyEval_ReleaseLock()
la aplicación se bloqueó rápidamente en una llamada posterior al PyImport_ExecCodeModule()
.
¿Qué me falta aquí?
Esto es incorrecto y potencialmente dañino: 'PyEval_SaveThread' siempre debe estar junto con' PyEval_RestoreThread'. Como se explica en otra parte (http://stackoverflow.com/a/15471525/1600898), no intente liberar el bloqueo después de inicializarlo; simplemente deja que Python lo libere como parte de su trabajo habitual. – user4815162342
No veo por qué es dañino si pones todas las llamadas a python en un bloque _Block_ _Allow_. Por otro lado, si no llamas a 'PyEval_SaveThread();', tu hilo principal bloqueará el acceso de otros hilos a Python. En otras palabras, 'deadlocks PyGILState_Ensure()'. – khkarens
Esto es lo único que funciona tanto para incrustar Python como para llamar a un módulo de extensión. –