हमें मल्टीप्रोसेसिंग कब कहना चाहिए।


96

मैं निम्नलिखित के रूप में 'multiprocess.Pool.imap_unordered' का उपयोग कर रहा हूं

from multiprocessing import Pool
pool = Pool()
for mapped_result in pool.imap_unordered(mapping_func, args_iter):
    do some additional processing on mapped_result

क्या मुझे लूप के लिए कॉल करने की आवश्यकता है pool.closeया pool.joinउसके बाद?


मैं आम तौर पर फोन pool.join()तो pool.close()एक बार मैं पूल धागे के सभी शुरू कर दिया है, लेकिन मैं उपयोग करने की कोशिश नहीं की है pool.imap_unordered()एक iterable के रूप में।
बाम्क्लूर

8
कॉल ज्वाइन या बंद करने की बात क्या है? मैंने उन्हें फोन नहीं किया और मेरा कोड ठीक काम कर रहा है। हालाँकि, मुझे चिंता है कि उन लोगों को न बुलाने का परिणाम ज़ोंबी प्रक्रियाओं या अन्य सूक्ष्म चीजों में होगा।
बजे

जवाबों:


113

नहीं, तुम नहीं, लेकिन यह शायद एक अच्छा विचार है अगर आप अब पूल का उपयोग नहीं करने जा रहे हैं।

इस एसओ पोस्ट में टिम पीटर्स द्वारा कॉल करने pool.closeया कहने के कारण pool.joinअच्छे हैं :

जैसा कि Pool.close () में, आपको कॉल करना चाहिए कि कब - और केवल तभी - जब आप पूल के उदाहरण में अधिक कार्य सबमिट करने वाले नहीं हैं। इसलिए पूल.क्लोज () को आम तौर पर तब कहा जाता है जब आपके मुख्य कार्यक्रम का समानांतर भाग समाप्त हो जाता है। तब कार्यकर्ता प्रक्रियाएं समाप्त हो जाएंगी जब पहले से ही सौंपे गए सभी काम पूरे हो चुके हैं।

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


9
एक के बाद एक फोन करना बेहतर है?
RSHAP

9
ऐसा लगता है कि लोग pool.close()पहले और pool.join()दूसरे को कॉल करना पसंद करते हैं । यह आपके बीच काम को जोड़ने की अनुमति देता है pool.close()और pool.join()निष्पादन को समाप्त करने के लिए पूल के लिए प्रतीक्षा करने की आवश्यकता नहीं है।
बाम्क्लूर

34
बस @ बाम्क्लूर की टिप्पणी में जोड़ने के लिए - pool.close()पहले कॉल करना केवल एक अच्छा विचार नहीं है , यह वास्तव में अनिवार्य है। से डॉक्स : एक कॉल करना होगा close()या terminate()उपयोग करने से पहले join()
बोगड

4
@Bogd लेकिन यह अनिवार्य क्यों है? क्या आप इस प्रश्न का उत्तर दे सकते हैं ?
अग्रध्वज

Agdhruvs सवाल का जवाब बहुत बढ़िया होगा!
सचेतक

44

मेरे पास मेमोरी का एक ही मुद्दा था क्योंकि मेमोरी उपयोग पायथन के मल्टीप्रोसेसिंग के साथ बढ़ रहा है। जब मैंने उपयोग नहीं किया था pool.close()और pool.join()जब pool.map()एक फ़ंक्शन के साथ उपयोग किया गया था जो कि लेवेन्सहाइट दूरी की गणना करता था। फ़ंक्शन ने ठीक काम किया, लेकिन एक Win7 64 मशीन पर कचरा ठीक से एकत्र नहीं किया गया था, और मेमोरी उपयोग हर बार नियंत्रण से बाहर हो रहा था, जब तक कि यह पूरे ऑपरेटिंग सिस्टम को नीचे नहीं ले जाता है। यहाँ वह कोड है जो रिसाव को ठीक करता है:

stringList = []
for possible_string in stringArray:
    stringList.append((searchString,possible_string))

pool = Pool(5)
results = pool.map(myLevenshteinFunction, stringList)
pool.close()
pool.join()

पूल को बंद करने और जुड़ने के बाद मेमोरी लीक हो गई।


1
मैं ERROR: Terminated with signal 15पहले सफाई कोड जोड़ रहा था, pool.close();pool.join();लेकिन उस सफाई कोड को जोड़ने के बाद मुझे कंसोल संदेश नहीं मिले। इसलिए मुझे कम से कम अपने संस्करण पर संदेह है, सी 7 से अजगर 2.7, कि पूल शायद किसी भी तरह से बिल्कुल सफाई नहीं कर रहा था।
ट्रेवर बॉयड स्मिथ
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.