2013-08-11 10 views
23

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

मैंने Python multiprocessing.Pool: when to use apply, apply_async or map? पढ़ा है और यह उपयोगी था, लेकिन अभी भी मेरे अपने प्रश्न थे।

तो एक ही रास्ता है कि मैं यह कर सकता है:

प्रश्न मैं इस लागू करने के लिए है: 1) के बाद से ब्लॉक में शामिल होने के लिए बुला प्रक्रिया पूर्ण होने तक ... इस का क्या मतलब है p1 प्रक्रिया को समाप्त करने के लिए किया पी 2 प्रक्रिया से पहले लात मार दिया गया है? मैं हमेशा .join() को पूल.प्ली() और pool.apply_sync() के समान समझा जाता हूं।() प्राप्त करें (जहां) मूल प्रक्रिया एक और प्रक्रिया (कार्य) लॉन्च नहीं कर सकती है जब तक कि चालू एक रन पूरा नहीं हो जाता है।

अन्य वैकल्पिक होगा की तरह कुछ:

def foo(): 
    pass 

def bar(): 
    pass 
pool = Pool(processes=2)    
p1 = pool.apply_async(foo) 
p1 = pool.apply_async(bar) 

प्रश्न यह लागू करने के लिए मेरे पास होगा: 1) मैं एक pool.close की ज़रूरत है(), pool.join()? 2) क्या पूल प्राप्त करने से पहले पूल.मैप() उन्हें पूरा कर देगा? और यदि हां, तो क्या वे अभी भी एसिंच चला रहे हैं? 3) pool.apply_async() पूल के साथ प्रत्येक प्रक्रिया को करने से अलग कैसे होगा .apply() 4) प्रक्रिया के साथ पिछले कार्यान्वयन से यह अलग कैसे होगा?

उत्तर

22

आपके द्वारा सूचीबद्ध दो परिदृश्य एक ही चीज़ को पूरा करते हैं लेकिन थोड़ा अलग तरीकों से।

पहले परिदृश्य दो अलग-अलग प्रक्रियाओं (उन्हें P1 और P2 कहते हैं) शुरू होता है और P1 चल foo और P2 चल bar शुरू होता है, और फिर इंतजार कर रहा है जब तक दोनों प्रक्रियाओं उनके संबंधित कार्यों को समाप्त कर दिया है।

दूसरा परिदृश्य दो प्रक्रियाओं को शुरू करता है (उन्हें क्यू 1 और क्यू 2 कहते हैं) और पहले क्यू 1 या क्यू 2 पर foo शुरू होता है, और फिर क्यू 1 या क्यू 2 पर bar शुरू होता है। तब कोड तब तक प्रतीक्षा करता है जब तक कि दोनों फ़ंक्शन कॉल वापस नहीं आतीं।

तो नेट परिणाम वास्तव में वही है, लेकिन पहले मामले में आपको विभिन्न प्रक्रियाओं पर foo और bar चलाने की गारंटी है।

विशिष्ट प्रश्न आप संगामिति के बारे में था के रूप में, एक Process पर .join() विधि वास्तव में प्रक्रिया जब तक ब्लॉक करता है समाप्त हो गया है, लेकिन क्योंकि तुम दोनों P1 और P2 (अपनी पहली स्थिति में) पर .start() कहा जाता है, से पहले में शामिल होने तो दोनों प्रक्रियाओं को असंकालिक रूप से चलाया जाएगा। हालांकि, दुभाषिया पी 2 खत्म होने की प्रतीक्षा करने से पहले पी 1 खत्म होने तक प्रतीक्षा करेगा।

पूल परिदृश्य के बारे में आपके प्रश्नों के लिए, आपको तकनीकी रूप से pool.close() का उपयोग करना चाहिए, लेकिन यह इस बात पर निर्भर करता है कि आपको इसके बाद क्या चाहिए (यदि यह केवल दायरे से बाहर हो जाता है तो आपको इसे बंद करने की आवश्यकता नहीं है)।pool.map() एक पूरी तरह से अलग प्रकार का जानवर है, क्योंकि यह पूल प्रक्रियाओं में एक ही फ़ंक्शन (असीमित रूप से) के तर्कों का एक गुच्छा वितरित करता है, और तब तक प्रतीक्षा करता है जब तक कि सभी फ़ंक्शन कॉल परिणामों की सूची लौटने से पहले पूरा नहीं हो जाते।

9

चूंकि आप कर्ल कॉल से डेटा प्राप्त कर रहे हैं, इसलिए आप आईओ-बाउंड हैं। ऐसे मामले में grequests काम में आ सकता है। ये वास्तव में न तो प्रक्रियाएं हैं और न ही धागे बल्कि कोरआउट - हल्के धागे हैं। यह आपको असीमित HTTP अनुरोध भेजने की अनुमति देगा, और उसके बाद CPU-bound भाग को गति देने के लिए multiprocessing.Pool का उपयोग करें।

1) कॉलिंग प्रक्रिया पूरी होने तक ब्लॉक में शामिल होने के बाद ... क्या इसका मतलब है कि पी 2 प्रक्रिया को खत्म करने से पहले पी 1 प्रक्रिया खत्म होनी चाहिए?

हाँ, p2.join()p1.join() अर्थ p1 समाप्त हो गया है वापस आ गया है के बाद कहा जाता है।

1)), pool.join() मैं एक pool.close जरूरत है (क्या

आप कर सकते थे close() और join() (कर के बिना अनाथ प्रक्रियाओं के साथ खत्म हो अगर प्रक्रियाओं indefinetly की सेवा)

2) क्या पूल.मैप() परिणाम प्राप्त करने से पहले उन्हें पूरा कर देगा? और यदि हां, तो क्या वे अभी भी एसिंच चला रहे हैं?

वे असीमित रूप से भाग गए हैं, लेकिन map() सभी कार्यों को पूरा होने तक अवरुद्ध कर दिया गया है।

3) कैसे pool.apply_async हैं(),() pool.apply साथ प्रत्येक प्रक्रिया कर

pool.apply() ब्लॉक कर रहा है से अलग तो बुनियादी तौर पर आप तुल्यकालिक प्रसंस्करण करना होगा।

4) कैसे इस प्रक्रिया के साथ पिछले कार्यान्वयन से अलग होगा

संभावना एक कार्यकर्ता foo साथ किया जाता है इससे पहले कि आप लागू bar ताकि आप सभी काम कर रही एक भी कार्यकर्ता के साथ खत्म हो सकता है। इसके अलावा, यदि आपके कर्मचारियों में से एक Pool स्वचालित रूप से एक नया स्पॉन्स करता है (आपको कार्य को फिर से लागू करने की आवश्यकता होगी)।

सारांश में: मैं नहीं बल्कि Pool साथ जाना होगा - यह निर्माता-उपभोक्त मामलों के लिए एकदम सही है और सभी कार्य-वितरण तर्क का ख्याल रखता है।

+1

क्या आप सुनिश्चित हैं कि पी 2 प्रक्रिया को खत्म करने से पहले पी 2 प्रक्रिया को खत्म करना है क्योंकि()? http://bpaste.net/show/ruHgFTAAMkN4UT2INPqu/ से आउटपुट पी 1 खत्म होने से पहले पी 2 किक्स की तरह दिखता है। – dman

+2

मेरा मतलब था, 'पी 1' शामिल होने के बाद' पी 2' शामिल हो जाएगा। गलतफहमी के लिए माफी। बेशक, जैसे ही उचित 'प्रारंभ() 'वापस आ गया है, दोनों प्रक्रियाएं बंद हो जाती हैं। –

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