Liberando GIL y mezclando hilos de C y Python

Lanzamiento de GIL en la extensión C:
proporcione un código de extensión C y uno debe ejecutarlo simultáneamente con otros subprocesos en el intérprete de Python. Para este Global Interpreter Lock (GIL) tiene que ser liberado y readquirido.

Código n.º 1: Liberación y readquisición de GIL mediante la inserción de las siguientes macros

#include "Python.h"
...
PyObject *pyfunc(PyObject *self, PyObject *args)
{
    ...
    Py_BEGIN_ALLOW_THREADS
      
    // Threaded C code. 
    // Must not use Python API functions
    ...
    Py_END_ALLOW_THREADS
    ...
    return result;
}

Mezcla de subprocesos de C y Python:
considerando una situación, que un programa dado involucra una combinación de C, Python y subprocesos. Pero algunos de los subprocesos dados se crean desde C fuera del control del intérprete de Python y también ciertos subprocesos utilizan funciones en la API C de Python.

¿Cuál es la solución entonces?
Si hay una combinación de Python, C y subprocesos, es importante la inicialización y la gestión adecuadas del Bloqueo de intérprete global (GIL) de Python . El código dado a continuación explica la situación, su código se puede usar en cualquier lugar (antes de la creación de subprocesos) en el programa C.

Código #2:

#include <Python.h>
...
if (!PyEval_ThreadsInitialized())
{
    PyEval_InitThreads();
}
...

Para cualquier C que involucre objetos de Python o la API de Python C, GIL debe adquirirse y liberarse primero. Esto se puede realizar usando PyGILState_Ensure()y PyGILState_Release()como en el código que se proporciona a continuación. Cada llamada a PyGILState_Ensure()debe tener una llamada correspondiente a PyGILState_Release().

Código #3:

...
// Make sure we own the GIL
// Use functions in the interpreter
PyGILState_STATE state = PyGILState_Ensure();
  
...
// Restore previous GIL state and return 
PyGILState_Release(state);
...

Nota:
no es tan fácil tener tantas cosas funcionando a la vez, lo que implica una combinación de código Python, código C y sus subprocesos. Para hacerlo, se debe tener cuidado de que el intérprete esté correctamente inicializado y que el código C que involucra al intérprete tenga las llamadas de gestión GIL adecuadas, todo debería funcionar.
Además, la PyGILState_Ensure() llamada no se adelanta ni interrumpe inmediatamente al intérprete. Si actualmente se está ejecutando otro código, esta función se bloqueará hasta que ese código decida liberar el bloqueo de intérprete global (GIL) .

Publicación traducida automáticamente

Artículo escrito por manikachandna97 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *