2009-09-26 18 views
8

के रूप में मैं C++ में पायथन एम्बेड करने पर काम कर रहा हूं। कुछ अनोखे मामले में मुझे उसी धागे में दुभाषिया के दो अलग-अलग उदाहरणों की आवश्यकता होती है।पाइथन दुभाषिया एक सी ++ वर्ग

क्या मैं पाइथन दुभाषिया को सी ++ कक्षा में लपेट सकता हूं और दो या दो से अधिक कक्षा के उदाहरणों से सेवाएं प्राप्त कर सकता हूं?

उत्तर

14

मैं अलग धागे में विभिन्न दुभाषियों के लिए 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 

ध्यान दें कि आपको प्रत्येक दुभाषिया के लिए एक चर MyThreadState की आवश्यकता है उदाहरण!

अंत में मुख्य थ्रेड में खत्म:

PyEval_RestoreThread(mainThreadState); 
Py_Finalize(); 

वहाँ कई दुभाषिया उदाहरणों का प्रयोग करते हैं (वे पूरी तरह से स्वतंत्र नहीं होने लगते हैं) के साथ कुछ प्रतिबंध हैं, लेकिन ज्यादातर मामलों में यह समस्याएं पैदा करने के लिए नहीं लगता है।

4

आप कर सकते हैं, लेकिन मैं आपको एक मानक कार्यान्वयन के दौरान एक पायथन दुभाषिया को फिर से लागू नहीं करने की सलाह दूंगा। पाइथन के साथ इंटरफ़ेस करने के लिए बूस्ट :: पायथन का उपयोग करें।

+0

बूस्ट पायथन पाइथन सी एपिस का उपयोग करता है। क्या Py_Initialize() को कॉल करके दो बार दुभाषिया शुरू करना संभव है? –

6

कॉलिन Py_Initialize() दो बार अच्छी तरह से काम नहीं करेगा, हालांकि Py_NewInterpreter आप जो करने की कोशिश कर रहे हैं उसके आधार पर काम कर सकते हैं। दस्तावेज़ों को ध्यान से पढ़ें, आपको इसे कॉल करते समय जीआईएल को पकड़ना होगा।

+0

मुझे लगता है कि मुझे अपने प्रश्न का सीधा जवाब नहीं मिलेगा। आपके उत्तर ने मुझे कुछ इनपुट दिए हैं जिन पर मैं काम शुरू कर सकता हूं। मेरे द्वारा वर्णित परिदृश्य की खोज शुरू करने के लिए Py_NewInterpreter सही विकल्प प्रतीत होता है। इस पर आधारित मैं आपका जवाब स्वीकार कर रहा हूं। –

1

मुझे नहीं लगता कि आप ऐसा करने वाले पहले व्यक्ति हैं, दुर्भाग्य से मेरा मानना ​​है कि यह संभव नहीं है। क्या आप पाइथन इंटरपरर्स को अलग प्रक्रियाओं के रूप में चलाने और आरपीसी का उपयोग करने में सक्षम हैं?

0
  • आप पाइथन दुभाषिया को अपने एप्लिकेशन मेमोरी स्पेस के बाहर रहने दे सकते हैं। बस एक डीएलएल में दुभाषिया एम्बेड करें।
  • आप & को दो अलग-अलग दुभाषियों को अनुकरण करने के लिए पाइथन संदर्भों को सहेज सकते हैं।
1

मोज़ेक का उत्तर मेरी स्थिति में काम नहीं करता है जहां मेरा मॉड्यूल एक मेजबान अनुप्रयोग के लिए एक प्लगइन है जो पहले से ही पाइथन शुरू करता है। मैं इसे निम्नलिखित कोड के साथ काम करने में सक्षम था।

// 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) पर कॉल करने से दुभाषिया को भी अमान्य कर दिया गया।

संबंधित मुद्दे