पर अनुरोध की तुलना में अधिक प्रक्रियाओं को उत्पन्न करता है, मैं प्रक्रियाओं के बीच कार्यों को वितरित करने के लिए पाइथन की मल्टीप्रोसेसिंग। पुल क्लास का उपयोग कर रहा हूं।multiprocessing.Pool केवल Google क्लाउड
सरल मामले में काम करता है के रूप में उम्मीद:
from multiprocessing import Pool
def evaluate:
do_something()
pool = Pool(processes=N)
for task in tasks:
pool.apply_async(evaluate, (data,))
एन प्रक्रियाओं उत्पन्न हुए हैं, और वे लगातार कार्य है कि मैं apply_async में पारित के माध्यम से काम करते हैं। अब, मेरे पास एक और मामला है जहां मेरे पास कई अलग-अलग जटिल वस्तुएं हैं जिन्हें प्रत्येक को कम्प्यूटेशनल रूप से भारी गतिविधि करने की आवश्यकता होती है। मैंने शुरुआत में प्रत्येक ऑब्जेक्ट को अपनी मल्टीप्रोसेसिंग बनाने की अनुमति दी थी। मांग पर पुल जब यह काम पूरा कर रहा था, लेकिन अंततः मैं बहुत सारी फाइलें खोलने के लिए ओएसईआरर में भाग गया, भले ही मैं मानता कि पूल को कचरा मिलेगा उपयोग।
किसी भी दर पर, मैंने तय कर लिया वैसे भी बेहतर होगा इन जटिल वस्तुओं में से प्रत्येक के संगणना के लिए एक ही पूल साझा करने के लिए:
from multiprocessing import Pool
def evaluate:
do_something()
pool = Pool(processes=N)
class ComplexClass:
def work:
for task in tasks:
self.pool.apply_async(evaluate, (data,))
objects = [ComplexClass() for i in range(50)]
for complex in objects:
complex.pool = pool
while True:
for complex in objects:
complex.work()
अब, जब मैं अपने कंप्यूटर से एक (OS X पर इस चलाने , पायथन = 3.4), यह अपेक्षा के अनुसार काम करता है। एन प्रक्रियाएं उत्पन्न होती हैं, और प्रत्येक जटिल वस्तु उनमें से प्रत्येक के बीच अपने कार्यों को वितरित करती है। हालांकि, जब मैंने इसे किसी अन्य मशीन पर चलाया (Google क्लाउड इंस्टेंस उबंटू, पायथन = 3.5) चला रहा है, तो यह बड़ी संख्या में प्रक्रियाओं (>> एन) को जन्म देता है और पूरे कार्यक्रम में विवाद के कारण रोक लगती है।
अगर मैं अधिक जानकारी के लिए पूल की जाँच करें:
import random
random_object = random.sample(objects, 1)
print (random_object.pool.processes)
>>> N
सब कुछ सही लग रहा है। लेकिन यह स्पष्ट रूप से नहीं है। कोई विचार क्या हो रहा है?
अद्यतन
मैं कुछ अतिरिक्त लॉगिंग गयी। मैंने सादगी के लिए पूल आकार 1 सेट किया। पूल के भीतर, एक कार्य पूरा होने के बाद, मैं multiprocessing मॉड्यूल से current_process() को मुद्रित करता हूं, साथ ही os.getpid() का उपयोग करके कार्य के पिड को प्रिंट करता हूं। यह कुछ इस तरह का परिणाम:
<ForkProcess(ForkPoolWorker-1, started daemon)>, PID: 5122
<ForkProcess(ForkPoolWorker-1, started daemon)>, PID: 5122
<ForkProcess(ForkPoolWorker-1, started daemon)>, PID: 5122
<ForkProcess(ForkPoolWorker-1, started daemon)>, PID: 5122
...
फिर, htop का उपयोग कर वास्तव में गतिविधि को देख, मैं कई प्रक्रियाओं (वस्तु प्रति एक बहु पूल साझा करने) इस रूप में सभी उपभोक्ता CPU चक्र दिखाई दे रही है, क्या हो रहा है तो में जिसके परिणामस्वरूप बहुत ओएस विवाद कि प्रगति बहुत धीमी है। 5122 मूल प्रक्रिया प्रतीत होता है।
आप 'multiprocessing.log_to_stderr (logging.DEBUG)' का एक कॉल जोड़ सकते हैं, डीबगिंग की सहायता के लिए अधिक लॉग मुद्रित किया जाएगा। – georgexsh
@georgexsh मैंने इसे डिबगिंग में सहायता के लिए जोड़ा है, लेकिन एकमात्र आउटपुट मैं इसे देखता हूं: [DEBUG/MainProcess] हैंडल भेजने के लिए श्रोता और धागा शुरू करना 3537 20 0 3624M 250M 32572 टी 0.0 0.4 0: 04.35 पायथन ensemble .py [INFO/MainProcess] ने temp निर्देशिका/tmp/pymp-06sjm3do – TSM
बनाया है, मुझे लगता है कि आप 'if __name__ == '__main __' का उपयोग कर रहे हैं:' अपने पूल की सुरक्षा के लिए चाल? – BlackBear