سؤال

أنا أعمل على تضمين بيثون في C ++. في بعض الحالة الغريبة، أحتاج إلى مثيلتين منفصلين من المترجم في نفس الخيط.

هل يمكنني التفاف مترجم بايثون في فئة C ++ واحصل على خدمات من مثيلتين أو أكثر؟

هل كانت مفيدة؟

المحلول

لقد استخدمت Py_newinterpreter لمجموعة مفترضة مختلفة في مواضيع مختلفة، ولكن يجب أن يعمل هذا أيضا للعديد من المترجمين الفوريين داخل موضوع واحد:

في الخيط الرئيسي:

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

لاحظ أنك تحتاج إلى myreadstate متغير لكل مثيل مترجم!

أخيرا النهاية في الخيط الرئيسي:

PyEval_RestoreThread(mainThreadState);
Py_Finalize();

هناك بعض القيود التي تستخدم العديد من حالات الترجمة الشاملة (تبدو مستقلة تماما)، ولكن في معظم الحالات لا يبدو أن هذا لا يبدو أن هذا يتسبب في مشاكل.

نصائح أخرى

كالين Py_Initialize() مرتين لن تعمل بشكل جيد، ولكن Py_NewInterpreter يمكن أن تعمل، اعتمادا على ما تحاول القيام به. اقرأ المستندات بعناية، يجب عليك حمل GIL عند الاتصال بهذا.

يمكنك، لكنني أنصحك بعدم إعادة تنفيذ مترجم ثعبان عندما يكون هناك تطبيق قياسي. يستخدم دفعة :: بيثون إلى واجهة مع بيثون.

لا أعتقد أنك أول شخص يريد القيام بذلك، لسوء الحظ، أعتقد أنه غير ممكن. هل أنت قادر على تشغيل تقبير بيثون كعمليات منفصلة واستخدام RPC؟

لم تعمل إجابة Mosaik في وضعي حيث تكون الوحدة النمطية مكونا إضافيا لتطبيق مضيف تهيئة بيثون بالفعل. كنت قادرا على الحصول عليها للعمل مع التعليمات البرمجية التالية.

// 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) يبدو أن يبطل المترجم أيضا.

  • يمكنك السماح لمجمودي Python مباشرة في خارج مساحة ذاكرة التطبيق الخاصة بك. فقط تضمين مترجم في DLL.
  • يمكنك إعداد وحفظ سياقات Python لمحاكاة اثنين من المترجمين الفوريين المختلفة.
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top