Frage

Ich arbeite Python in C ++ auf dem Einbetten. In einigen eigenartigen Fall benötige ich zwei separate Instanzen des Dolmetschers in demselben Thread.

Kann ich Python-Interpreter wickeln, um eine C ++ Klasse und erhalten Leistungen von zwei oder mehreren Klasseninstanzen?

War es hilfreich?

Lösung

Ich habe Py_NewInterpreter für verschiedene Dolmetscher in verschiedenen Threads verwendet, aber dies auch für mehrere Dolmetscher in einem Thread funktionieren soll:

In dem Haupt-Thread:

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

Für jeden Dolmetscher Instanz (in jedem Thread):

// 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

Beachten Sie, dass Sie eine Variable myThreadState für jede Interpreter-Instanz müssen!

Schließlich wird das Ziel im Hauptthread:

PyEval_RestoreThread(mainThreadState);
Py_Finalize();

Es gibt einige Einschränkungen mit mehreren Interpreter-Instanzen verwenden (sie scheinen nicht völlig unabhängig zu sein), aber in den meisten Fällen scheint dies nicht zu Problemen führen.

Andere Tipps

Callin Py_Initialize() zweimal nicht gut funktionieren, aber Py_NewInterpreter können arbeiten, je nachdem, was Sie zu tun versuchen. Lesen Sie die Dokumentation sorgfältig, haben Sie die GIL zu halten, wenn diese aufgerufen wird.

Sie können, aber ich würde empfehlen Sie kein Python-Interpreter neu zu implementieren, wenn es eine Standard-Implementierung ist. Mit boost :: python , um eine Schnittstelle mit Python.

Ich glaube nicht, dass Sie die erste Person zu wollen, dies zu tun, leider glaube ich es nicht möglich ist. Sind Sie in der Lage, den Python interperters als separate Prozesse und verwenden RPC?

laufen

mosaik Antwort nicht in meiner Situation arbeiten, wo mein Modul ein Plugin an eine Host-Anwendung, die bereits Python initialisiert. Ich war in der Lage, um es mit dem folgenden Code zu arbeiten.

// 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)

Wenn ich PyEval_AcquireLock() das Programm blockiert aufgerufen und die Funktion kehrt nicht zurück. Ferner ruft PyEval_ReleaseThread(myState) schien auch den Dolmetscher ungültig zu machen.

  • Sie können lassen Sie den Python-Interpreter Live außerhalb Ihrer Anwendung Speicherplatz. Gerade einbetten den Interpreter in einer DLL.
  • Sie können einrichten und Python Kontexte speichern zwei Dolmetscher zu simulieren.
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top