2009-08-04 13 views
32

मेरे पास एक पायथन एप्लिकेशन है जो डेटा संग्रह का संग्रह करता है और उस संग्रह में डेटा के प्रत्येक टुकड़े के लिए यह एक कार्य करता है। इस कार्य को पूरा करने में कुछ समय लगता है क्योंकि इसमें देरी हो रही है। इस देरी के कारण, मैं नहीं चाहता कि डेटा के प्रत्येक टुकड़े बाद में कार्य करें, मैं चाहता हूं कि वे सभी समानांतर में हों। क्या मुझे मल्टीप्रोसेस का उपयोग करना चाहिए? या इस ऑपरेशन के लिए थ्रेडिंग?पाइथन में मल्टीप्रोसेस या थ्रेडिंग?

मैंने थ्रेडिंग का उपयोग करने का प्रयास किया लेकिन कुछ परेशानी थी, अक्सर कुछ कार्य वास्तव में कभी नहीं आग लगते थे।

+0

आपका "डेटा संग्रह" कितना बड़ा है। यदि यह बड़ा है, तो आप प्रत्येक के लिए धागे या प्रक्रिया शुरू नहीं करना चाहेंगे। –

+0

आमतौर पर डेटा के 1, 2, या 3 टुकड़े। – Ryan

+0

@ एसएलओटी - आप डेटा के आकार की तुलना में थ्रेड/प्रक्रियाओं की संख्या को कितनी छोटी संख्या में सीमित कर देंगे? –

उत्तर

0

सीपीथॉन के थ्रेडिंग मॉडल का उपयोग करने से आपको कोई प्रदर्शन सुधार नहीं मिलेगा, क्योंकि कचरा संग्रह को संभालने के तरीके के कारण थ्रेड वास्तव में समानांतर में निष्पादित नहीं होते हैं। मल्टीप्रोसेस समानांतर निष्पादन की अनुमति देगा। जाहिर है इस मामले में आपको अपनी समांतर नौकरियों के खेत के लिए कई कोर उपलब्ध हैं।

this related question में और अधिक जानकारी उपलब्ध है।

+4

यह सच नहीं है। यह आपको बहुत अधिक प्रदर्शन सुधार नहीं देगा क्योंकि यह कहेंगे, सी या सी ++, लेकिन कुछ समरूपता होती है। विशेष रूप से यदि आप I/O बाध्य हैं तो थ्रेड मदद करते हैं। – Christopher

+0

मुझे एहसास नहीं हुआ - जानकारी के लिए धन्यवाद। यहां एक बाहरी संदर्भ है: http://mail.python.org/pipermail/python-dev/2008-May/079461.html। इस बेंचमार्क में, आप I/O-बाध्य समस्याओं के लिए सुधार देख सकते हैं जो आप वर्णन करते हैं। हालांकि, यह इंगित करने लायक है कि सीपीयू-बाध्य समस्या वास्तव में ** धीमी गति से ** ** के साथ 2 पायथन धागे के साथ! ऐसा लगता है कि आपके आवेदन के लिए प्रोफाइलिंग आवश्यक है। –

7

डेटा के छोटे संग्रह के लिए, बस subprocess.Popen के साथ उपप्रोसेसेस बनाएं।

प्रत्येक सबप्रोसेस इसे सीधे स्टडीन से या कमांड लाइन तर्क से डेटा का टुकड़ा प्राप्त कर सकता है, क्या यह प्रसंस्करण कर रहा है, और परिणाम को केवल आउटपुट फ़ाइल में लिख सकता है।

जब उपप्रोसेस सभी समाप्त हो गए हैं (या समय समाप्त हो गए हैं, तो आप बस आउटपुट फ़ाइलों को मर्ज करें।

बहुत आसान।

+3

यह वास्तव में एक भारी समाधान है। न केवल आपको बाहरी प्रक्रिया में डेटा को खिलाने की व्यवस्था करना है, आपके पास भारी ओवरहेड है। – Christopher

+1

@ क्रिस्टोफर। बिंदु सादगी है। यूनिक्स दुनिया 40 वर्षों तक इस तकनीक का उपयोग कर रही है। यह अच्छी तरह से काम करता है क्योंकि यह आसान है। इसके अलावा, ओवरहेड वास्तव में "विशाल" नहीं है क्योंकि आप एक ही बाइनरी छवि के कई उदाहरण चला रहे हैं। यह जीएनयू/लिनक्स द्वारा अच्छी तरह से अनुकूलित है। –

+8

@ एसएलॉट: सिर्फ इसलिए कि इसका उपयोग लंबे समय तक किया गया है, इसका मतलब यह नहीं है कि यह एक अच्छा समाधान है। यह विशेष रूप से गणना की समस्याओं के लिए एक अच्छा समाधान नहीं है। ओवरहेड "बड़े पैमाने पर" है क्योंकि आपके पास सभी प्रति-प्रक्रिया संरचनाओं के साथ-साथ कई कर्नेल संक्रमणों की विलंबता की स्मृति ओवरहेड है। पायथन मल्टीप्रोसेसिंग मॉड्यूल वास्तव में उपप्रोसेस की तरह एक नई "प्रक्रिया" नहीं बनाता है। यह एक नया दुभाषिया संदर्भ बनाता है, जो एक नई ओएस-स्तरीय प्रक्रिया बनाने से कहीं अधिक हल्का है। – Christopher

7

आप Stackless Python पर विचार कर सकते हैं। यदि आपके पास उस फ़ंक्शन पर नियंत्रण है जो लंबे समय तक लेता है, तो आप वहां कुछ stackless.schedule() एस फेंक सकते हैं (अगले कोरआउट में उपज कह रहे हैं), या फिर आप set Stackless to preemptive multitasking कर सकते हैं।

stackless में, आप धागे की जरूरत नहीं है, लेकिन tasklets या greenlets जो अनिवार्य रूप से बहुत हल्के सूत्र हैं। यह इस अर्थ में बहुत अच्छा काम करता है कि मल्टीटास्किंग जाने के लिए बहुत कम सेटअप के साथ एक बहुत अच्छा ढांचा है।

हालांकि, स्टैकलेस पोर्टेबिलिटी में बाधा डालता है क्योंकि आपको कुछ मानक पायथन पुस्तकालयों को प्रतिस्थापित करना होता है - स्टैकलेस सी स्टैक पर निर्भरता को हटा देता है। यह बहुत पोर्टेबल है यदि अगले उपयोगकर्ता को स्टैकलेस भी इंस्टॉल किया गया है, लेकिन यह शायद ही कभी मामला होगा।

29

आप वास्तव में बंधे की गणना कर रहे हैं, multiprocessing module का उपयोग कर शायद सबसे हल्का वजन समाधान है (दोनों स्मृति की खपत और कार्यान्वयन कठिनाई के मामले में।)

आप आई/ओ बाध्य का उपयोग कर रही threading module आमतौर पर दे देंगे कर रहे हैं आप अच्छे परिणाम सुनिश्चित करें कि आप थ्रेड सुरक्षित भंडारण (कतार की तरह) का उपयोग अपने धागे को डेटा सौंपने के लिए करते हैं। या फिर उन्हें डेटा का एक टुकड़ा सौंपें जो उनके लिए अनोखा होता है जब वे पैदा होते हैं।

PyPy प्रदर्शन पर केंद्रित है। इसमें कई विशेषताएं हैं जो गणना-बाध्य प्रसंस्करण में सहायता कर सकती हैं। उन्हें सॉफ़्टवेयर ट्रांजेक्शनल मेमोरी के लिए भी समर्थन है, हालांकि यह अभी तक उत्पादन की गुणवत्ता नहीं है। वादा यह है कि आप मल्टीप्रोसेसिंग (जिसमें कुछ अजीब आवश्यकताएं हैं) की तुलना में सरल समांतर या समवर्ती तंत्र का उपयोग कर सकते हैं।

Stackless Python भी एक अच्छा विचार है। जैसा कि ऊपर दर्शाया गया है, स्टैकलेस में पोर्टेबिलिटी समस्याएं हैं। Unladen Swallow वादा कर रहा था, लेकिन अब निष्क्रिय है।Pyston गति पर केंद्रित एक और (अधूरा) पायथन कार्यान्वयन है। यह पीईपीई के लिए एक दृष्टिकोण अलग कर रहा है, जो बेहतर (या सिर्फ अलग) गति उत्पन्न कर सकता है।

0

यदि आप आसानी से डेटा को विभाजित और अलग कर सकते हैं, तो ऐसा लगता है कि आपको केवल उस विभाजन को बाहरी रूप से करना चाहिए, और उन्हें अपने प्रोग्राम की कई प्रक्रियाओं में फ़ीड करना चाहिए। (यानी धागे के बजाए कई प्रक्रियाएं)

0

आयरनपीथन में वास्तविक मल्टीथ्रेडिंग है, सीपीथॉन और इसकी जीआईएल के विपरीत। तो आप जो कर रहे हैं उसके आधार पर यह देखने लायक हो सकता है। लेकिन ऐसा लगता है कि आपके उपयोग के मामले मल्टीप्रोसेसिंग मॉड्यूल के लिए बेहतर अनुकूल है।

उस व्यक्ति को जो स्टैकलेस पायथन की सिफारिश करता है, मैं उस पर एक विशेषज्ञ नहीं हूं, लेकिन ऐसा लगता है कि वह सॉफ़्टवेयर "मल्टीथ्रेडिंग" के बारे में बात कर रहा है, जो वास्तव में समानांतर नहीं है (अभी भी एक भौतिक धागे में चलता है, इसलिए एकाधिक कोरों तक स्केल नहीं किया जा सकता है।) यह एसिंक्रोनस (लेकिन अभी भी सिंगल-थ्रेडेड, गैर समांतर) अनुप्रयोग को संरचना करने का एक वैकल्पिक तरीका है।

9

कार्य अनुक्रमिक रूप से चलते हैं लेकिन आपके पास समानांतर में चलने वाले भ्रम हैं। जब आप फ़ाइल या कनेक्शन I/O के लिए उपयोग करते हैं और क्योंकि लाइटवेइट्स होते हैं तो कार्य अच्छे होते हैं।

पूल के साथ मल्टीप्रोसेस आपके लिए सही समाधान हो सकता है क्योंकि प्रक्रियाएं समानांतर में चलती हैं इसलिए गहन कंप्यूटिंग के साथ बहुत अच्छी होती है क्योंकि प्रत्येक प्रक्रिया एक सीपीयू (या कोर) में चलती है।

सेटअप मल्टीप्रोसेस बहुत आसान हो सकता है:

from multiprocessing import Pool 

def worker(input_item): 
    output = do_some_work() 
    return output 

pool = Pool() # it make one process for each CPU (or core) of your PC. Use "Pool(4)" to force to use 4 processes, for example. 
list_of_results = pool.map(worker, input_list) # Launch all automatically 
+0

क्या इसका मतलब यह है कि सभी कोर एक ही डेटा पर काम कर रहे हैं? क्या इनपुट_सूची को विभाजित करना और प्रत्येक खंड को अलग-अलग कोरों में पार करना संभव है? – Moj

0

आप Twisted को देखने के लिए चाहते हो सकता है। यह एसिंक्रोनस नेटवर्क कार्यों के लिए डिज़ाइन किया गया है।

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