2015-07-29 6 views
5

मैं पाश यानीProcess.join() और कतार बड़ी संख्या

N = 1000000 
for i in xrange(N): 
    #do something 

multiprocessing.Process प्रयोग करने के लिए विभाजित करने के लिए कोशिश कर रहा हूँ के साथ काम नहीं है और यह एन के छोटे मूल्यों के लिए अच्छी तरह से काम समस्या पैदा होती है जब मैं एन के बड़े मूल्यों का उपयोग करता हूं। P.join() से पहले या उसके दौरान कुछ अजीब होता है और प्रोग्राम प्रतिक्रिया नहीं देता है। अगर मैं प्रिंट करता हूं, तो q.put (i) के बजाय फ़ंक्शन की परिभाषा में f सबकुछ अच्छी तरह से काम करता है।

मैं किसी भी मदद की सराहना करता हूं। कोड यहाँ है।

from multiprocessing import Process, Queue 

def f(q,nMin, nMax): # function for multiprocessing 
    for i in xrange(nMin,nMax): 
     q.put(i) 

if __name__ == '__main__': 

    nEntries = 1000000 

    nCpu = 10 
    nEventsPerCpu = nEntries/nCpu 
    processes = [] 

    q = Queue() 

    for i in xrange(nCpu): 
     processes.append(Process(target=f, args=(q,i*nEventsPerCpu,(i+1)*nEventsPerCpu))) 

    for p in processes: 
     p.start() 

    for p in processes: 
     p.join() 

    print q.qsize() 

उत्तर

8

आप सीमा के बिना अपने कतार बढ़ने की कोशिश कर रहे हैं, और यदि आप ऐसा अपने मुख्य प्रक्रिया है कि एक पूरा करने के लिए के लिए इंतज़ार कर रुक गई है, एक उपप्रक्रिया कि कतार में कमरे के लिए इंतज़ार कर रहा है अप करने के लिए शामिल हो रहे हैं, और यह कभी मर्जी।

यदि आप शामिल होने से पहले कतार से डेटा खींचते हैं तो यह ठीक काम करेगा।

एक तकनीक आप इस्तेमाल कर सकते हैं कुछ इस तरह है:

while 1: 
    running = any(p.is_alive() for p in processes) 
    while not queue.empty(): 
     process_queue_data() 
    if not running: 
     break 

प्रलेखन के अनुसार, p.is_alive(), एक अंतर्निहित में शामिल होने के प्रदर्शन करना चाहिए लेकिन यह भी सूचित करते हैं कि सबसे अच्छा अभ्यास हो सकता है प्रकट होता है इसके बाद सभी धागे पर स्पष्ट रूप से शामिल होने के लिए।

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

CPU की संख्या के लिए प्रक्रियाओं की संख्या को कम करने के अलावा, कुछ आसान फिक्स यह थोड़ा तेजी से (फिर से, परिस्थितियों के आधार पर) इस प्रकार दिखाई देंगे बनाने के लिए:

liveprocs = list(processes) 
while liveprocs: 
    try: 
     while 1: 
      process_queue_data(q.get(False)) 
    except Queue.Empty: 
     pass 

    time.sleep(0.5) # Give tasks a chance to put more data in 
    if not q.empty(): 
     continue 
    liveprocs = [p for p in liveprocs if p.is_alive()] 
+0

धन्यवाद! यह काम करता हैं। – Puibo

+0

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

+0

सीपीयू की संख्या के लिए अधिक प्रक्रियाएं अच्छी हैं - सीपीयू की संख्या से पहले भी यदि प्रक्रिया कभी-कभी रुक जाएगी। जिस तरह से आपके आंत संबंधी प्रश्न को बुलाया गया था, मैंने सोचा कि शायद यह एक प्रोग्रामिंग होमवर्क समस्या थी - आपको एहसास नहीं हुआ कि आपके पास एक शक्तिशाली मशीन थी :) वैसे भी, एक मीट्रिक विचार करने के लिए है कि आप चीजों को एक-थ्रेडेड बनाकर कितनी गति प्राप्त कर रहे हैं - - अगर आपको 10 प्रक्रियाओं के साथ 10 एक्स स्पीडअप मिल रहा है (संभावना नहीं है), यह बहुत अच्छा है! प्रक्रियाओं के बीच निर्भरता (प्रतीक्षा) कम करना महत्वपूर्ण है - जैसा कि आपने देखा है, आपको कतार को निकालना है। –

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