9

私はpythonをc ++に埋め込むことに取り組んでいます。いくつかの特殊なケースでは、同じスレッドでインタープリターの 2 つの別個のインスタンスが必要です。

Python インタープリターを C++ クラスにラップして、2 つ以上のクラス インスタンスからサービスを取得できますか?

4

6 に答える 6

14

異なるスレッドの異なるインタープリターに Py_NewInterpreter を使用しましたが、これは 1 つのスレッド内の複数のインタープリターでも機能するはずです。

メインスレッドで:

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

各インタープリター インスタンス (任意のスレッド内) について:

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

各インタープリターインスタンスに対して変数 myThreadState が必要であることに注意してください!

最後に、メイン スレッドの仕上げ:

PyEval_RestoreThread(mainThreadState);
Py_Finalize();

複数のインタプリタ インスタンスの使用にはいくつかの制限があります (それらは完全に独立していないようです) が、ほとんどの場合、これは問題を引き起こさないようです。

于 2012-01-13T10:28:54.683 に答える
6

CallinPy_Initialize()は2回うまく機能しませんPy_NewInterpreterが、何をしようとしているかによっては機能する可能性があります。ドキュメントを注意深く読んでください。これを呼び出すときはGILを保持する必要があります。

于 2009-09-26T10:01:10.227 に答える
4

可能ですが、標準の実装がある場合は、Pythonインタープリターを再実装しないことをお勧めします。boost::pythonを使用してPythonとインターフェースします。

于 2009-09-26T06:28:08.557 に答える
2

mosaik の答えは、私のモジュールがすでに Python を初期化しているホスト アプリケーションへのプラグインであるという私の状況では機能しませんでした。次のコードで動作させることができました。

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

PyEval_AcquireLock()私がブロックされたプログラムを呼び出したとき、関数は戻りませんでした。さらに、呼び出しPyEval_ReleaseThread(myState)はインタープリターも無効にしているように見えました。

于 2015-03-18T21:24:31.970 に答える
1

あなたがこれをやりたいと思う最初の人ではないと思いますが、残念ながらそれは不可能だと思います。Pythonインターパーターを個別のプロセスとして実行し、RPCを使用できますか?

于 2009-10-04T01:00:56.600 に答える
0
  • Python インタープリターをアプリケーションのメモリ空間の外に置くことができます。インタープリターを DLL に埋め込むだけです。
  • Python コンテキストを設定および保存して、2 つの異なるインタープリターをシミュレートできます。
于 2009-10-05T08:45:55.490 に答える