2012-04-14 18 views
7

यह (काफी सरलीकृत उदाहरण) ठीक (पायथन 2.6.6, डेबियन निचोड़) काम करता है:पाइथन मल्टीप्रोसेसिंग के लिए वैकल्पिक उपयोग पैटर्न वैश्विक राज्य के प्रसार से परहेज करते हैं?

from multiprocessing import Pool 
import numpy as np 

src=None 

def process(row): 
    return np.sum(src[row]) 

def main(): 
    global src 
    src=np.ones((100,100)) 

    pool=Pool(processes=16) 
    rows=pool.map(process,range(100)) 
    print rows 

if __name__ == "__main__": 
    main() 

हालांकि, सिखाया जा रहा वैश्विक राज्य बुरा के वर्षों के बाद !!!, मेरे सभी सहज ज्ञान मुझे कह रहे हैं मैं वास्तव में वास्तव में नहीं बल्कि के करीब कुछ लिख किया जाएगा:

from multiprocessing import Pool 
import numpy as np 

def main(): 
    src=np.ones((100,100)) 

    def process(row): 
     return np.sum(src[row]) 

    pool=Pool(processes=16) 
    rows=pool.map(process,range(100)) 
    print rows 

if __name__ == "__main__": 
    main() 

लेकिन निश्चित है कि काम नहीं करता है की (कुछ अचार करने में असमर्थ ऊपर लटका हुआ है)।

यहां उदाहरण छोटा है, लेकिन जब तक आप कई "प्रक्रिया" फ़ंक्शंस जोड़ते हैं, और उनमें से प्रत्येक कई अतिरिक्त इनपुट पर निर्भर है ... ठीक है, यह सब कुछ 30 साल पहले बेसिक में लिखे गए कुछ याद दिलाता है । उचित कार्यों के साथ राज्य को कम से कम समेकित करने के लिए कक्षाओं का उपयोग करने का प्रयास एक स्पष्ट समाधान लगता है, लेकिन अभ्यास में doesn't seem to be that easy लगता है।

क्या मल्टीप्रोसेसिंग.pool का उपयोग करने के लिए कुछ अनुशंसित पैटर्न या शैली है जो वैश्विक कार्य के प्रसार से बचने के लिए प्रत्येक समारोह का समर्थन करने के लिए मैं समानांतर नक्शा बनाना चाहता हूं?

"मल्टीप्रोसेसिंग पेशेवर" का अनुभव कैसे किया जाता है?

अद्यतन: ध्यान दें कि मैं वास्तव में बहुत बड़ा सरणियों प्रसंस्करण में रुचि हूँ, इसलिए जो ऊपर में बदलाव src अचार प्रत्येक कॉल/यात्रा लोगों को जो पूल के कार्यकर्ता प्रक्रियाओं में यह कांटा के रूप में लगभग रूप में अच्छा नहीं कर रहे हैं।

+0

मैं एक अनुभवी खिलाड़ी या कुछ भी बहु नहीं कर रहा हूँ, लेकिन मुझे आप से पूछना जाने क्यों आप नहीं कर सकते बस pool.map (प्रक्रिया, उत्पाद ([src], रेंज (100)) करें) और दोनों चर को तर्क के रूप में स्वीकार करने के लिए प्रक्रिया फ़ंक्शन को बदलें? क्या यह भी अत्यधिक अक्षम है? – luke14free

+0

@ luke14free: हां जो प्रत्येक कॉल के लिए src सरणी को उठाएगा, और मैं वास्तव में उपरोक्त नमूना कोड की तुलना में बहुत अधिक डेटा/सरणी में रूचि रखता हूं, इसलिए आदर्श नहीं। प्रक्रिया पूल के साथ, जिस बिंदु पर पूल बनाया जाता है, उसे पूल कार्यकर्ता प्रक्रियाओं में फंसे हुए हैं और उनके लिए "मुफ्त में" पढ़ने के लिए उपलब्ध है। विचार, हालांकि, नाबालिगों में अधिक मामूली "नियंत्रण चर" (जैसे ध्वज) राज्य डालने से बचने में मदद करेगा, धन्यवाद। – timday

उत्तर

5

तुम हमेशा इस तरह की एक प्रतिदेय वस्तु गुजर सकता है, तो वस्तु साझा राज्य CONTAINE कर सकते हैं:

from multiprocessing import Pool 
import numpy as np 

class RowProcessor(object): 
    def __init__(self, src): 
     self.__src = src 
    def __call__(self, row): 
     return np.sum(self.__src[row]) 

def main(): 
    src=np.ones((100,100)) 
    p = RowProcessor(src) 

    pool=Pool(processes=16) 
    rows = pool.map(p, range(100)) 
    print rows 

if __name__ == "__main__": 
    main() 
+0

दिलचस्प लग रहा है ... इस शैली को एक कोशिश करेगा और रिपोर्ट करेगा ... – timday

+0

Yup बहुत अच्छी तरह से धन्यवाद काम करता है; अलविदा अलविदा globals। आम तौर पर मैं यह देखने के लिए समाधान स्वीकार करने से पहले लंबे समय तक इंतजार करूँगा कि कुछ और चालू हो गया है लेकिन यह सही है। मैंने पहले इस समस्या के लिए कक्षाओं की कोशिश की थी और कोई सफलता नहीं थी; ऐसा लगता है कि कॉल करने योग्य सभी फर्क पड़ता है। – timday

+2

क्या यह कॉल करने योग्य नहीं होगा और आप वापस वर्ग में हैं? –