2014-11-05 11 views
9

के साथ win32com का उपयोग कर मैं चेरीपी के साथ एक वेब ऐप पर काम कर रहा हूं जिसे COM के माध्यम से कुछ एप्लिकेशन तक पहुंचने की आवश्यकता है।multithreading

अभी मैं प्रत्येक अनुरोध के साथ आवेदन का एक नया उदाहरण बना देता हूं, जिसका अर्थ यह है कि प्रत्येक अनुरोध वास्तविक कार्य के लिए आवेदन शुरू करने के लिए 3 सेकंड और 0.01 प्रतीक्षा करता है।

मैं प्रत्येक COM एप्लिकेशन को एक बार शुरू करना चाहता हूं और इसे जीवित रखना चाहता हूं और इसे निम्नलिखित अनुरोधों पर कुछ सेकंड के लिए पुन: उपयोग करना चाहता हूं क्योंकि अधिकांश समय इसका उपयोग 5-10 AJAX अनुरोधों के विस्फोट से किया जाता है, फिर घंटों के लिए कुछ भी नहीं ।

क्या चेरीपी एप्लिकेशन के सभी धागे में एक COM abject साझा करना संभव है?

यहां कुछ प्रयोगों का सारांश दिया गया है जो दिखाते हैं कि यह प्रत्येक अनुरोध पर अब कैसे काम कर रहा है और यह थ्रेड में कैसे काम नहीं करता है।

निम्नलिखित कोड को सफलतापूर्वक शुरू होता है और बंद हो जाता है एक्सेल:

>>> import pythoncom, win32com.client 
>>> def start(): 
    global xl 
    xl = win32com.client.Dispatch('Excel.Application') 

>>> def stop(): 
    global xl 
    xl.quit() 
    xl = None 

>>> start() 
>>> stop() 

लेकिन निम्नलिखित कोड एक्सेल शुरू होता है और 3 सेकंड के बाद यह बंद कर देता है।

>>> import pythoncom, win32com.client, threading, time 
>>> def start(): 
    global xl 
    pythoncom.CoInitialize() 
    xl = win32com.client.Dispatch('Excel.Application') 
    time.sleep(3) 

>>> threading.Thread(target=start).start() 

मैं CoInitialize() करने के लिए कॉल जोड़ा अन्यथा xl वस्तु (this post देखें) कार्य नहीं करेगा।

और मैंने 3 सेकंड पॉज़ जोड़ा, इसलिए मैं टास्क मैनेजर पर देख सकता था कि EXCEL.EXE प्रक्रिया शुरू होती है और 3 सेकंड के लिए जीवित है।

यह धागा शुरू होने के बाद क्यों मर जाता है?

मैंने CoInitialize() के प्रलेखन की जांच की, लेकिन मुझे समझ में नहीं आया कि यह बहुप्रचारित वातावरण में काम करने के लिए संभव है या नहीं।

+1

चाल (उर्फ, मुक्त पिरोया) बहु-क्रम अपार्टमेंट के लिए धागा का उपयोग प्रारंभ करने में हो सकता है। 'COINIT_APARTMENTTHREADED' विकल्प के साथ [CoInitializeEx] (http://docs.activestate.com/activepython/2.5/pywin32/pythoncom__CoInitializeEx_meth.html) आज़माएं। कोड स्निपेट के लिए – tdelaney

उत्तर

7

यदि आप एकाधिक थ्रेड में win32com का उपयोग करना चाहते हैं तो आपको थोड़ा और काम करने की आवश्यकता है क्योंकि COMObject सीधे थ्रेड पर नहीं भेजा जा सकता है। आप CoMarshalInterThreadInterfaceInStream() और CoGetInterfaceAndReleaseStream() उपयोग करने के लिए धागे के बीच उदाहरण के पारित करने के लिए की जरूरत है:

import pythoncom, win32com.client, threading, time 

def start(): 
    # Initialize 
    pythoncom.CoInitialize() 

    # Get instance 
    xl = win32com.client.Dispatch('Excel.Application') 

    # Create id 
    xl_id = pythoncom.CoMarshalInterThreadInterfaceInStream(pythoncom.IID_IDispatch, xl) 

    # Pass the id to the new thread 
    thread = threading.Thread(target=run_in_thread, kwargs={'xl_id': xl_id}) 
    thread.start() 

    # Wait for child to finish 
    thread.join() 

def run_in_thread(xl_id): 
    # Initialize 
    pythoncom.CoInitialize() 

    # Get instance from the id 
    xl = win32com.client.Dispatch(
      pythoncom.CoGetInterfaceAndReleaseStream(xl_id, pythoncom.IID_IDispatch) 
    ) 
    time.sleep(5) 


if __name__ == '__main__': 
    start() 

अधिक जानकारी के लिए देखें: https://mail.python.org/pipermail/python-win32/2008-June/007788.html

+1

धन्यवाद। यह काफी उपयोगी था। – Sanjit

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