2013-04-01 4 views
7

में मल्टीप्रोसेसिंग के साथ बाल प्रक्रियाओं को सही तरीके से कैसे समाप्त करें मेरे पास कुछ कॉलबैक फ़ंक्शन हैं और मैं एकाधिक प्रक्रियाओं के रूप में लॉन्च करना चाहता हूं और उन्हें सभी को मूल प्रक्रिया से सिग्नल के माध्यम से समाप्त करना है।पाइथन

ऐसा करने का मेरा वर्तमान तरीका multiprocessing.Value के साथ साझा c_bool बना रहा है और इसे True पर सेट कर रहा है, फिर इसे बनाए जाने पर मेरी सभी प्रक्रियाओं में इसे वितरित कर रहा है।

while myC_bool: ...keep running... 

मैं तो बस bool False करने के लिए अपने माता-पिता की प्रक्रिया और सभी चाइल्ड प्रक्रियाओं से स्विच उनके अंतिम पाश और बाहर निकलने पूरा हो जाएगा कर सकते हैं: मेरी प्रक्रियाओं सब थोड़ी देर के पाश तो जैसे साझा bool का उपयोग कर चलाते हैं।

मुझे कई लोगों ने बताया है, और दस्तावेज़ों में पढ़ा है कि मल्टीप्रोसेसिंग का उपयोग करते समय साझा स्मृति का उपयोग करने से बचने की कोशिश करनी चाहिए। मुझे यह बताने का सबसे अच्छा तरीका बताया गया था कि प्रक्रिया को डिमननाइज़ करना है, इसे एक कस्टम सिग्नल हैंडलर दें और इसे एक सिग्ंट/सिगरेट/आदि भेजें ...

मेरा प्रश्न है, विशेष रूप से बूल का उपयोग करके बूल का उपयोग करना लूप जीवित है और केवल मेरे माता-पिता की प्रक्रिया से इसका मूल्य बदलता है, और इसे कई बाल प्रक्रियाओं से पढ़ता है ताकि मेरे सभी बच्चे की प्रक्रियाएं जल्दी और सुरक्षित रूप से समाप्त हो सकें? मुझे लगता है कि उन सभी बच्चों के लिए सिग्नेट भेजने की तुलना में, सभी बच्चों के लिए एक साझा बूल को देखने के लिए कम ओवरहेड है।

क्या डिमोनाइजिंग बेहतर समाधान होगा? यदि ऐसा है तो मुझे समझने में कुछ मदद चाहिए क्यों।

उत्तर

9

अच्छे कारणों की एक बहुत कुछ अपने समाधान के साथ जाने के लिए कर रहे हैं:

  • यह संकेतों की तुलना के बारे में सोचना आसान है।
  • इससे निपटने के लिए कम क्रॉस-प्लेटफ़ॉर्म समस्याएं हैं।
  • आपके पास पहले से ही कोड है जो इस तरह से काम करता है।
  • यदि आप भविष्य में चाहते हैं तो यह "सुंदर शटडाउन" तंत्र जोड़ना आसान बनाता है।

... और इसी तरह।

ध्यान रखें कि जब तक आप उस multiprocessing और अंतर्निहित ओएस पुरातन, हर मंच आप के बारे में, यहाँ तुल्यकालन के बिना काम करने की गारंटी है परवाह पर, आप हर पहुंचने के संबंध किसी और एक Lock या कुछ डाल करने के लिए की जरूरत है अपने आप को साबित कर सकते हैं रखें साझा बूल के लिए। यह बिल्कुल जटिल नहीं है, लेकिन ... एक बार ऐसा करने के बाद, उदाहरण के लिए, Event साझा बूल के बिना भी आसान हो सकता है।

किसी भी दर पर, यदि उनमें से कोई भी कारण था, तो मैं बहुत अच्छा कहूंगा, ऐसा ही करें। लेकिन अपने प्रश्न के अनुसार, आप वास्तव में इस प्रदर्शन की वजह से चुना है:

मुझे लगता है सभी बच्चों के लिए कम भूमि के ऊपर से उन्हें

को sigints की एक्स संख्या भेजने के लिए बस, एक साझा bool को देखने के लिए मौजूद है

यदि आपका कारण है, तो आप लगभग निश्चित रूप से गलत हैं। बच्चों को कुछ लूप के माध्यम से साझा बूल (और साझा लॉक प्राप्त करें!) को हर बार देखना होगा, जबकि सिग्नल केवल एक बार प्रत्येक बच्चे को भेजा जाना चाहिए। तो, आपका ओवरहेड लगभग निश्चित रूप से इस तरह से अधिक होने जा रहा है।

लेकिन वास्तव में, मैं प्रति बच्चे प्रक्रिया के लिए एक सिग्नल भेजने के ओवरहेड की कल्पना नहीं कर सकता, या प्रति लूप प्रति बार एक इंटरप्रोसेस लॉक को पकड़ने की कल्पना नहीं कर सकता, किसी भी उपयोगी प्रोग्राम में बाधा के करीब कहीं भी है, तो ... क्यों उपरांत यहां पहली जगह भी मायने रखता है? सबसे सरल तरीके से सबसे ज्यादा समझ में आता है।

+0

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

+0

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

+0

@LISTERINE: ... कहा जा रहा है, यह उल्लेखनीय है कि ये विशेषताएं किसी कारण से मौजूद हैं: कभी-कभी मल्टीप्रोसेसिंग से शुरू करना और थ्रेडिंग की तरफ एक कदम उठाना (ए) थ्रेडिंग से शुरू करना और इससे दूर जाने की कोशिश करना, या (बी) अपने पूरे एल्गोरिदम को पुनर्गठित करना ताकि इसे साझा किए बिना कोड किया जा सके। – abarnert

2

चूंकि आप साझा चर को संशोधित करने के बारे में सावधान हैं, इसलिए यह ठीक होना चाहिए।

कई अलग-अलग समाधान संभव हैं। जैसे multiprocessing.Event का उपयोग करें, और प्रक्रिया सेट होने पर प्रक्रिया समाप्त हो जाती है। या multiprocessing.Connection ऑब्जेक्ट्स (पाइप से) का उपयोग कर। उत्तरार्द्ध का इस्तेमाल माता-पिता और बच्चों के बीच दो-तरफा संचार के लिए किया जा सकता है। बच्चों को रोकने के लिए संकेतों की तरह, माता-पिता की पुष्टि के बाद।

0

जो लोग आपको बताते हैं "ऐसा नहीं करते" गलत हैं। साझा स्मृति का बिंदु मल्टीप्रोसेसरों के बीच स्मृति साझा करना है और यह वही है जो आप कर रहे हैं।

आपके पास एक समाधान है कि 1) सरल है, और 2) काम करता है। संकेत/डेमॉन दृष्टिकोण 1) वास्तव में अच्छा है और 2) सही ढंग से कोड करने के लिए कठिन और 3) समझने के लिए बहुत कठिन है।

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

अपनी जमीन खड़े हो जाओ।

+0

आपको वास्तव में विश्वास नहीं करना चाहिए "अधिकांश अनुप्रयोगों के लिए कैश फ्लशिंग अक्सर स्वचालित रूप से पर्याप्त होता है"। यदि आप यह सुनिश्चित करने के लिए नहीं जानते हैं कि आपके द्वारा हर प्लेटफ़ॉर्म पर आपके एप्लिकेशन के लिए अक्सर पर्याप्त (या हमेशा!) होता है, तो आपको स्पष्ट रूप से सिंक्रनाइज़ करने की आवश्यकता होती है। अन्यथा, आप बहुत अधिक गारंटी दे रहे हैं कि आपका कोड पहले बड़े डेमो पर दुर्घटनाग्रस्त हो जाएगा, या आप ह्यूसेनबग का पीछा करने वाले हफ्तों खर्च करेंगे जो केवल कुछ उपयोगकर्ताओं की मशीनों पर होता है (और निश्चित रूप से वे उपयोगकर्ता होंगे उपयोगी बग रिपोर्ट जमा करने के लिए कोई सुराग नहीं है)। – abarnert

+0

आपकी प्रतिक्रिया के लिए धन्यवाद, मुझे पता नहीं था कि आपने जिस गड़बड़ी का उल्लेख किया था वह भी एक जटिलता थी जिसे मैं सामना कर सकता था। ऐसा लगता है कि मेरे पास कुछ और शोध हो सकता है। – LISTERINE