2015-04-12 5 views
7

साथ बहु सूत्रण मैं एक सी ++ प्रोग्राम सी एपीआई मेरा एक अजगर पुस्तकालय उपयोग करने के लिए उपयोग करता है। पाइथन लाइब्रेरी और सी ++ दोनों कोड बहुप्रचारित हैं।पायथन और सी एपीआई

विशेष रूप से, सी ++ प्रोग्राम का एक थ्रेड एक पाइथन ऑब्जेक्ट को तत्काल करता है जो threading.Thread से प्राप्त होता है। मुझे उस ऑब्जेक्ट पर कॉल करने में सक्षम होने के लिए मेरे सभी सी ++ धागे की आवश्यकता है।

मेरी पहली कोशिशों से (मैं मूर्खतापूर्ण वस्तु को मुख्य थ्रेड से तुरंत चालू करता हूं, फिर कुछ समय प्रतीक्षा करें, फिर विधि को कॉल करें) मैंने देखा कि ऑब्जेक्ट से जुड़े पायथन थ्रेड का निष्पादन बस जैसे ही बंद हो जाता है निष्पादन सी ​​++ कार्यक्रम में वापस आता है।

यदि निष्पादन पायथन के साथ रहता है (उदाहरण के लिए, यदि मैं PyRun_SimpleString("time.sleep(5)"); पर कॉल करता हूं) पाइथन थ्रेड का निष्पादन पृष्ठभूमि में जारी रहता है और प्रतीक्षा समाप्त होने तक सब कुछ ठीक काम करता है और निष्पादन सी ​​++ पर वापस चला जाता है।

मैं जाहिर है कुछ गलत कर रहा हूँ। दोनों मेरे सी ++ और पायथन मल्टीथ्रेड किए गए और एक-दूसरे के साथ काम करने में सक्षम बनाने के लिए मुझे क्या करना चाहिए? मेरे पास मैदान में कोई पिछला अनुभव नहीं है इसलिए कृपया कुछ भी न मानें!

उत्तर

10

चरणों का एक सही क्रम आपको बस इतना करना कोशिश कर रहे हैं प्रदर्शन करने के लिए है:

  • मुख्य थ्रेड में:

    1. प्रारंभ अजगर Py_Initialize* का उपयोग कर।
    2. प्रारंभ अजगर PyEval_InitThreads() का उपयोग कर समर्थन सूत्रण।
    3. सी ++ धागा शुरू करें।

इस समय, मुख्य थ्रेड अभी भी GIL है।

  • एक सी ++ धागा में:
    1. PyGILState_Ensure() का उपयोग कर जीआईएल प्राप्त।
    2. एक नया पायथन थ्रेड ऑब्जेक्ट बनाएं और इसे शुरू करें।
    3. PyGILState_Release() का उपयोग कर जीआईएल छोड़ दें।
    4. सो जाओ, कुछ उपयोगी करें या थ्रेड से बाहर निकलें।

क्योंकि मुख्य थ्रेड जीआईएल रखती है, इस सूत्र जीआईएल प्राप्त करने के लिए इंतजार कर रहे होंगे। यदि मुख्य धागा पायथन एपीआई को कॉल करता है तो यह समय-समय पर जीआईएल को पाइथन थ्रेड को थोड़ी देर के लिए निष्पादित करने की इजाजत देता है।

  • मुख्य थ्रेड में वापस
    1. रिलीज GIL, धागे PyEval_SaveThread()
    2. का उपयोग अन्य अजगर कॉल का उपयोग करने प्रयास करने से पहले चलाने के लिए सक्षम करने के लिए, का उपयोग कर जीआईएल पुनः प्राप्त PyEval_RestoreThread()

मुझे संदेह है कि आप अंतिम चरण खो रहे हैं - मुख्य धागे में जीआईएल जारी करना, पायथन थ्रेड की इजाजत देना निष्पादन हेतु।

मेरे पास एक छोटा लेकिन पूरा उदाहरण है जो वास्तव में this link पर करता है।

0

जब आप पाइथन के threading.Thread से कॉलबैक करते हैं तो शायद आप Global Interpreter Lock अनलॉक नहीं करते हैं।

ठीक है, अगर तुम नंगे अजगर के सी एपीआई का उपयोग कर रहे हैं आप कैसे जारी करने के लिए/जीआईएल अधिग्रहण के बारे में some documentation here है,। लेकिन सी ++ का उपयोग करते समय, मुझे आपको चेतावनी देना चाहिए कि यह आपके सी ++ कोड में फेंकने वाले किसी भी अपवाद पर टूट सकता है। See here

सामान्य अपनी सी ++ समारोह है कि लंबे समय के लिए चलाता है, गिल और लॉक अनलॉक जब भी यह फिर से सी पायथन एपीआई का उपयोग करना चाहिए में से किसी में

+0

मुझे खेद है, लेकिन मुझे लगता है कि यह ठीक से समझ में नहीं आता है। यहां मैं क्या करता हूं: 1) 'PyGILState_STATE gstate; gstate = PyGILState_Ensure(); ' 2) अजगर उद्देश्य यह है कि से' threading.Thread' विरासत बनाएं 3) 'PyGILState_Release (gstate);' 4) कुछ सेकंड (C++) में के लिए नींद रन फ़ंक्शन, ऑब्जेक्ट को थोड़ी देर में कुछ प्रिंट करना चाहिए, लेकिन यह केवल कुछ ही मिलीसेकंड के लिए स्पष्ट रूप से करता है। मैं क्या गलत कर रहा हूं..? –

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