2009-12-18 24 views
7

हम एक जटिल जीयूआई के साथ एक बड़े आवेदन को फिर से फैक्टरिंग पर विचार कर रहे हैं जो बैक एंड के एक decoupled फैशन में अलग है (नया पाइथन 2.6) मल्टीप्रोसेसिंग मॉड्यूल का उपयोग करने के लिए। जीयूआई/बैकएंड इंटरफ़ेस दोनों दिशाओं में संदेश ऑब्जेक्ट्स के साथ पंक्तियों का उपयोग करता है।पाइथन मल्टीप्रोसेसिंग का उपयोग करने में कोई समस्या क्या होगी?

एक चीज जिसे मैंने अभी निष्कर्ष निकाला है (तात्कालिक रूप से, लेकिन इसकी पुष्टि करने में संकोच न करें) यह है कि "ऑब्जेक्ट पहचान" मल्टीप्रोसेसिंग इंटरफेस में संरक्षित नहीं होगी। वर्तमान में जब हमारे जीयूआई बैक एंड के लिए एक संदेश प्रकाशित करते हैं, तो यह एक विशेषता के रूप में संलग्न परिणाम के साथ एक ही संदेश वापस प्राप्त करने की अपेक्षा करता है। यह कुछ मामलों में लौटने वाले संदेशों की पहचान करने के लिए ऑब्जेक्ट पहचान (if received_msg is message_i_sent:) का उपयोग करता है ... और ऐसा लगता है कि मल्टीप्रोसेसिंग के साथ काम नहीं करना है।

यह सवाल क्या "gotchas" यह आप वास्तविक उपयोग या में देखा है की तरह पूछने के लिए कल्पना कर सकते हैं एक भोलेपन से, बहु मॉड्यूल का उपयोग कर विशेष रूप से एक मौजूदा एकल प्रक्रिया आवेदन पुनर्रचना में में मुठभेड़ होता है। कृपया निर्दिष्ट करें कि आपका उत्तर वास्तविक अनुभव पर आधारित है या नहीं। समस्या के लिए एक उपयोगी कामकाज प्रदान करने के लिए बोनस अंक।

संपादित करें: मैं इसे शुरू से ही समुदाय विकी (जो शायद बहुत से लोगों को उस पर ध्यान नहीं देता है, के रूप में बनाया: हालांकि इस सवाल के साथ अपने इरादे सामान्य में समस्याओं की विवरण इकट्ठा करने के लिए था, मैं मैं दो गलतियाँ की लगता है उन्हें प्रतिष्ठा अंक नहीं मिलेगा), और मैंने एक बहुत ही विशिष्ट उदाहरण शामिल किया - जबकि मैं जवाबों की सराहना करता हूं - शायद कई लोगों ने सामान्य प्रतिक्रियाओं के अनुरोध को याद किया है। मैं शायद एक नए प्रश्न में पुनः शब्द और फिर से पूछूंगा। अभी के लिए मैं केवल एक प्रश्न को स्वीकार करने के लिए सबसे अच्छा जवाब स्वीकार कर रहा हूं, जहां तक ​​यह मेरे द्वारा शामिल विशिष्ट उदाहरण से संबंधित है। उन लोगों के लिए धन्यवाद जिन्होंने जवाब दिया था!

+1

'message_i_sent.id = आईडी (message_i_sent)' और उसके बाद 'received_msg.id == message_i_sent.id' पहचान पकड़ लिया हल हो सकता है यदि (अगर यह मौजूद है)। यद्यपि बहुत सारे लोग हैं। – jfs

+0

@ जेएफ, धन्यवाद, मुझे लगता है कि मुझे अपने विकल्प से बेहतर पसंद है, जो कि 'संदेश .__ init__' में एक आईडी जोड़ रहा होता जो कि लॉक-संरक्षित वर्ग विशेषता का उपयोग करता है जो वृद्धि करता है। आपका दृष्टिकोण ऐसा लगता है कि इसे लॉकिंग या वृद्धि या कक्षा विशेषता की आवश्यकता नहीं होगी, लेकिन फिर भी पूरी तरह से मजबूत होगी। मैं इसे तब तक लिखूंगा जब तक आप या कोई और पहले नहीं करता। –

+0

@ जेएफ, हम्म .... अभी भी इसे सोच रहा है लेकिन अब मुझे इतना यकीन नहीं है। यदि आईडी 1234 वाला एक पुराना संदेश इंटरफ़ेस के माध्यम से चला गया, लेकिन भेजने के पक्ष में कोई संदर्भ नहीं रखा गया था, और फिर एक और संदेश एक ही आईडी() मिला और उसे एक संदर्भ के साथ भी भेजा गया, लेकिन * पहला * संदेश फिर वापस आ गया, यह गलत तरीके से मेल खाता होगा। मेरे पीछे आओ? –

उत्तर

2

मैंने मल्टीप्रोसेसिंग का उपयोग नहीं किया है, लेकिन प्रस्तुत की गई समस्याएं दो अन्य डोमेनों में वितरित अनुभवों के समान हैं: वितरित सिस्टम और ऑब्जेक्ट डेटाबेस। पायथन ऑब्जेक्ट पहचान एक आशीर्वाद और शाप हो सकता है!

सामान्य गॉथस के लिए, यह मदद करता है कि यदि आप जिस रीफैक्टरिंग कर रहे हैं, तो यह स्वीकार कर सकता है कि कार्यों को असीमित रूप से संभाला जा रहा है। यदि नहीं, तो आप आम तौर पर लॉक प्रबंधित करना समाप्त कर देंगे, और अलग-अलग प्रक्रियाओं का उपयोग कर प्राप्त किए गए अधिकांश प्रदर्शनों को उन ताले पर प्रतीक्षा करने के लिए खो दिया जाएगा। मैं यह भी सुझाव दूंगा कि आप प्रक्रियाओं में डीबगिंग के लिए कुछ मचान बनाने के लिए समय बिताएं। वास्तव में अतुल्यकालिक प्रक्रियाएं मन को पकड़ने और सत्यापित करने से कहीं अधिक कर रही हैं - या कम से कम मेरा दिमाग!

विशिष्ट मामले के लिए उल्लिखित, जब मैं कतारबद्ध और लौटाता हूं तो प्रक्रिया प्रक्रिया पर ऑब्जेक्ट पहचान प्रबंधित करता हूं। संसाधित होने के लिए कोई कार्य भेजते समय, कार्य को आईडी() के साथ एनोटेट करें, और आईडी() को कुंजी के रूप में उपयोग करके एक शब्दकोश में कार्य उदाहरण को छीनें। जब कार्य को अद्यतन/पूरा किया जाता है, तो शब्दकोश से आईडी() द्वारा सटीक कार्य वापस प्राप्त करें, और नए अपडेट किए गए राज्य को लागू करें। अब सटीक कार्य, और इसलिए इसकी पहचान, बनाए रखा जाएगा।

+0

@ शेन, बुरा नहीं (आईडी() विचार के लिए)। चूंकि हमारे पास अपेक्षाकृत कम जीयूआई बैकएंड संदेश हैं (इन-जीयूआई या इन-बैकएंड संदेश वॉल्यूम की तुलना में) राज्य की प्रतिलिपि को भारी बोझ नहीं होना चाहिए। यदि टैग किए गए और संग्रहीत संदेश को कभी वापस नहीं किया जाता है, तो स्मृति लीक का मौका होता है, लेकिन यह नियमित घटना नहीं होने पर एक बग से उत्पन्न असाधारण स्थिति होनी चाहिए। –

+1

@ पीटर, मैंने संदेश प्रविष्टि में टाइमआउट मान जोड़कर पहले उस समस्या का सामना किया है - या तो उपयोगकर्ता द्वारा प्रदान किया गया या अंतर्निहित। यदि उत्तर आने से पहले टाइमआउट समाप्त हो जाता है, तो एक त्रुटि हैंडलर प्रेषित करें। आपको देर से जवाब संभालना होगा। राज्य प्रतिलिपि के लिए, आप संदेश ऑब्जेक्ट से भेजने पर अब आवश्यक डेटा को हटा सकते हैं और अभी भी भेजने की तरफ पहचान पहचान बनाए रख सकते हैं। यदि आपके डेटा पायथन ऑब्जेक्ट्स नहीं हैं तो अन्य विकल्प भी हैं। स्मृति उन्मुख डेटा के लिए mmap या memcached का उपयोग करें, या बाहरी यूआरएल, फ़ाइलों और डेटाबेस के संदर्भ का उपयोग करें। –

1

अच्छी तरह से, गैर-सिंगलटन ऑब्जेक्ट (एस। "ए है कोई नहीं" या "ए झूठा") पर पहचान के लिए परीक्षण का परीक्षण आमतौर पर एक अच्छा अभ्यास नहीं होता है - यह जल्दी हो सकता है, लेकिन वास्तव में त्वरित कामकाज "है" "==" के लिए परीक्षण का आदान-प्रदान और पहचान को परिभाषित करने के लिए एक वृद्धिशील काउंटर का उपयोग करने के होगा:

# this is not threadsafe. 
class Message(object): 
    def _next_id(): 
     i = 0 
     while True: 
      i += 1 
      yield i 
    _idgen = _next_id() 
    del _next_id 

    def __init__(self): 
     self.id = self._idgen.next() 

    def __eq__(self, other): 
     return (self.__class__ == other.__class__) and (self.id == other.id) 

यह एक विचार हो सकता है।

इसके अलावा, सावधान रहें कि यदि आपके पास "कार्यकर्ता प्रक्रियाएं" हैं, तो स्मृति खपत थ्रेड-आधारित दृष्टिकोण से कहीं अधिक हो सकती है।

+0

धन्यवाद एलन। जो आप दिखाते हैं वह है जैसा कि मैंने जे.एफ. सेबेस्टियन को अपनी टिप्पणी में संदर्भित किया है कि अपवाद के साथ हमें बढ़ते ऑपरेशन के आसपास थ्रेड लॉक की आवश्यकता होगी। कार्यकर्ता प्रक्रियाओं के लिए, हमारे मामले में विचार अच्छी उपयोगकर्ता प्रतिक्रिया सुनिश्चित करने के लिए केवल जीयूआई को विभाजित करना है और जीयूआई में उपयोगकर्ता गतिविधि से बैक-एंड ऑपरेशंस पर प्रभाव को कम करना है। –

+0

हां, मैंने थ्रेडसेफ नहीं होने वाली बढ़ती चीज़ के बारे में भी एक टिप्पणी भी की थी, लेकिन मुझे लगता है कि साइट पर कट और पेस्ट करते समय मैंने इसे कटा हुआ किया। आपके उपयोग के मामले में आप एसिंक दृष्टिकोण को नियोजित करने के बारे में सोच सकते हैं, क्या आपने ट्विस्ट के बारे में सोचा है? –

+0

बैक-एंड वास्तव में एकाधिक रिएक्टरों के साथ बहुप्रचारित और असीमित दोनों है। यह "केवल थोड़ा मोड़" है ... एक पैकेज का उपयोग करता है जिसे हम "झुकाव" कहते हैं। इसे प्रभावी ढंग से एसिंक (एक थ्रेड) नहीं बनाया जा सकता है, इसलिए हम ऐसी चीजों के लिए लॉकिंग के साथ फंस गए हैं। हालांकि अच्छा विचार है। –

1

आप अपने प्रोजेक्ट GarlicSim से persistent पैकेज की कोशिश कर सकते हैं। यह एलजीपीएल है।

http://github.com/cool-RR/GarlicSim/tree/development/garlicsim/garlicsim/misc/persistent/

(उस में मुख्य मॉड्यूल persistent.py है)

मैं अक्सर इसे इस तरह का उपयोग करें:

# ... 
self.identity = Persistent() 

तो मैं एक पहचान है कि प्रक्रियाओं पर संरक्षित है।

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