Pregunta

Estoy trabajando en la incorporación de pitón para C ++. En algún caso peculiar requiero dos instancias independientes del intérprete en mismo hilo.

¿Puedo envolver Python intérprete a una clase de C ++ y obtener los servicios a partir de dos o más instancias de la clase?

¿Fue útil?

Solución

he utilizado Py_NewInterpreter para diferentes intérpretes en diferentes hilos, pero esto también debería funcionar para varios intérpretes dentro de un hilo:

En el hilo principal:

Py_Initialize();
PyEval_InitThreads();
mainThreadState = PyEval_SaveThread();

Para cada instancia de intérprete (en cualquier hilo):

// initialize interpreter
PyEval_AcquireLock();                // get the GIL
myThreadState = Py_NewInterpreter();
... // call python code
PyEval_ReleaseThread(myThreadState); // swap out thread state + release the GIL

... // any other code

// continue with interpreter
PyEval_AcquireThread(myThreadState); // get GIL + swap in thread state
... // call python code
PyEval_ReleaseThread(myThreadState);

... // any other code

// finish with interpreter
PyEval_AcquireThread(myThreadState);
... // call python code
Py_EndInterpreter(myThreadState);
PyEval_ReleaseLock();                // release the GIL

Tenga en cuenta que se necesita un myThreadState variable para cada instancia intérprete!

Por último el acabado en el hilo principal:

PyEval_RestoreThread(mainThreadState);
Py_Finalize();

Hay algunas restricciones en el uso de varios casos de interpretación (que parecen no ser totalmente independiente), pero en la mayoría de los casos esto no parece causar problemas.

Otros consejos

Py_Initialize() Callin dos veces no funcionará bien, sin embargo Py_NewInterpreter puede trabajar, dependiendo de lo que estamos tratando de hacer. Leer los documentos con cuidado, usted tiene que mantener el GIL cuando se llama a esto.

Se puede, pero me gustaría recomendar que no volver a implementar un intérprete de Python cuando hay una implementación estándar. Utilice impulso :: python para interactuar con Python.

No creo que usted es la primera persona que desee hacer esto, por desgracia, creo que no es posible. ¿Es capaz de ejecutar las interperters Python como procesos separados y utilizar RPC?

La respuesta de mosaik no funcionaba en mi situación en mi módulo es un plugin para una aplicación host que ya inicializa pitón. Yo era capaz de conseguir que funcione con el siguiente código.

// initialize interpreter
::PyEval_InitThreads();
::PyThreadState *mainThread = ::PyThreadState_Get();
myState = ::Py_NewInterpreter();
... // call python code
::PyThreadState_Swap(mainThread);

... // any other code

mainThread = ::PyThreadState_Swap(myState)
... // call python code
::PyThreadState_Swap(mainThread)

... // any other code

// finished with interpreter
mainThread = ::PyThreadState_Swap(myState)
::Py_EndInterpreter(myState);
::PyThreadState_Swap(mainThread)

Cuando llamé PyEval_AcquireLock() el programa bloqueado y la función no regresó. Además, PyEval_ReleaseThread(myState) llamando pareció invalidar el intérprete también.

  • Puede dejar que el intérprete de Python viven fuera de su espacio de memoria de la aplicación. Sólo incrustar el intérprete en una DLL.
  • Puede configurar y guardar contextos pitón para simular dos intérpretes diferentes.
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top