2009-10-16 11 views
6

में पाइथन जीआईएल जारी करना मुझे सी ++ में लिखी गई लाइब्रेरी मिली है जिसे मैं SWIG का उपयोग करके लपेटता हूं और पायथन में उपयोग करता हूं। आम तौर पर कुछ विधियों के साथ एक वर्ग होता है। समस्या यह है कि इन तरीकों को बुलाकर समय लेने वाला हो सकता है - वे मेरे आवेदन को लटका सकते हैं (इन विधियों को कॉल करते समय जीआईएल जारी नहीं किया जाता है)। तो मेरा सवाल है:सी ++ कोड

इन विधि कॉल के लिए जीआईएल जारी करने का सबसे आसान तरीका क्या है?

(मैं समझता हूँ कि अगर मैं एक सी पुस्तकालय का इस्तेमाल किया मैं कुछ अतिरिक्त सी कोड के साथ इस लपेट कर सकता है, लेकिन यहाँ मैं सी ++ और कक्षाओं का उपयोग करें)

उत्तर

1

आप सी कोई अंतर के लिए के रूप में ही API कॉल का उपयोग कर सकते हैं। "Python.h" शामिल करें और एपोप्रेट फ़ंक्शन को कॉल करें।

इसके अलावा, देखें कि क्या SWIG के पास टाइपमैप या कुछ ऐसा नहीं है जो इंगित करता है कि जीआईएल शूल्ड किसी विशिष्ट फ़ंक्शन के लिए नहीं रखा जाता है।

5

किसी भी विचार क्या बड़ा घूँट मैं एक जवाब वैसे भी :)

इस रिलीज करने के लिए की तरह कुछ का उपयोग का प्रयास करेंगे/प्राप्त जीआईएल है होने नहीं:

class GILReleaser { 
    GILReleaser() : save(PyEval_SaveThread()) {} 

    ~GILReleaser() { 
     PyEval_RestoreThread(save); 
    } 

    PyThreadState* save; 
}; 

और का कोड-ब्लॉक में अपने चुनकर, जारी करने के लिए आरए II उपयोग/प्राप्त गिल:

{ 
    GILReleaser releaser; 
    // ... Do stuff ... 
} 
+0

धन्यवाद, आपने मुझे कुछ समय बचाया। – Ellioh

5

असली समस्या यह है कि बड़ा घूँट अच्छी तरह से प्रलेखित नहीं है (मैं खोज के लिए बदलाव का उपयोग करने के लिए संकेत देखा;) है)।

ठीक है, मुझे पता चला है कि मैं बड़ा घूँट में इनलाइन कार्यों करते हैं और जारी करने के लिए/जीआईएल प्राप्त मैक्रो का उपयोग कर सकते हैं, यह इस तरह दिखता है:

%inline %{ 
    void wrappedFunction(OriginalObject *o, <parameters>) { 
    Py_BEGIN_ALLOW_THREADS 
    o->originalFunction(<parameters>); 
    Py_END_ALLOW_THREADS 
} 
%} 

इस समारोह मूल C++ मौजूद है, लेकिन में उपलब्ध नहीं है पायथन मॉड्यूल। यह वास्तव में वही है जो मैं चाहता था। (जो मैं चाहता हूं वह मूल विधि को लपेटना है जैसे कि पाइथन सजावट करता है)

+0

हेनरिक का प्रयोग करें। यह सही है, लेकिन खराब सी ++ अभ्यास है। जीआईएल को रिहा करने के बाद भी मुझे एक धक्का से आंकड़ों को निकालने में दुर्घटना हुई थी, इसलिए मैं आम तौर पर जीआईएल रिहाई और पुनः प्राप्त करने के बीच python.h से किसी भी फ़ंक्शन का उपयोग नहीं करता हूं। –