2012-01-09 15 views
7

मैंने लगभग 50 कक्षाएं लिखीं जिनका उपयोग मैं मशीनीकरण और थ्रेडिंग का उपयोग करके वेबसाइटों के साथ कनेक्ट करने और काम करने के लिए करता हूं। वे सभी एक साथ काम करते हैं, लेकिन वे एक-दूसरे पर निर्भर नहीं हैं। तो इसका मतलब है 1 वर्ग - 1 वेबसाइट - 1 धागा। यह विशेष रूप से कोड का प्रबंधन करने के लिए विशेष रूप से सुरुचिपूर्ण समाधान नहीं है, क्योंकि प्रत्येक वर्ग में बहुत से कोड दोहराए जाते हैं (लेकिन तर्कों को पारित करने के लिए इसे एक वर्ग में बनाने के लिए लगभग पर्याप्त नहीं है, क्योंकि कुछ साइटों को विधियों के बीच में पुनर्प्राप्त डेटा की अतिरिक्त प्रसंस्करण की आवश्यकता हो सकती है - 'लॉगिन' की तरह - दूसरों को शायद इसकी आवश्यकता नहीं है)। जैसा कि मैंने कहा, यह सुरुचिपूर्ण नहीं है - लेकिन यह काम करता है। कहने की जरूरत नहीं है कि मैं सभी सिफारिशों का स्वागत करता हूं कि प्रत्येक वेबसाइट दृष्टिकोण के लिए 1 वर्ग का उपयोग किये बिना इसे बेहतर तरीके से कैसे लिखना है। प्रत्येक वर्ग की अतिरिक्त कार्यक्षमता या समग्र कोड प्रबंधन जोड़ना एक कठिन काम है।थ्रेडेड पायथन कोड के मेमोरी उपयोग को कैसे कम करें?

हालांकि, मुझे पता चला, कि प्रत्येक धागा, 8MB स्मृति के बारे में लेता है तो 50 चल धागे के साथ के बारे में हम 400MB उपयोग को देख रहे हैं। अगर यह मेरे सिस्टम पर चल रहा था तो मुझे इसके साथ कोई समस्या नहीं होगी, लेकिन चूंकि यह केवल 1 जीबी मेमोरी के साथ वीपीएस पर चल रहा है, यह एक मुद्दा बनना शुरू हो रहा है। क्या आप मुझे बता सकते हैं कि मेमोरी उपयोग को कैसे कम किया जाए, या क्या कई साइटों के साथ काम करने के लिए कोई अन्य तरीका है?

मैं अगर यह अपने आवेदन की चर कि स्मृति, या कुछ और उपयोग कर रहा है में संग्रहीत डेटा है परीक्षण करने के लिए इस त्वरित परीक्षण अजगर कार्यक्रम का इस्तेमाल किया। जैसा कि आप निम्न कोड में देख सकते हैं, यह केवल नींद() फ़ंक्शन को प्रोसेस कर रहा है, फिर भी प्रत्येक थ्रेड 8 एमबी मेमोरी का उपयोग कर रहा है।

from thread import start_new_thread 
from time import sleep 

def sleeper(): 
    try: 
     while 1: 
      sleep(10000) 
    except: 
     if running: raise 

def test(): 
    global running 
    n = 0 
    running = True 
    try: 
     while 1: 
      start_new_thread(sleeper,()) 
      n += 1 
      if not (n % 50): 
       print n 
    except Exception, e: 
     running = False 
     print 'Exception raised:', e 
    print 'Biggest number of threads:', n 

if __name__ == '__main__': 
    test() 

जब मैं इस चलाने के लिए, उत्पादन होता है:

   total  used  free  shared buffers  cached 
Mem:   1536  1533   2   0   0   0 
-/+ buffers/cache:  1533   2 
Swap:   0   0   0 

वास्तविक:

50 
100 
150 
Exception raised: can't start new thread 
Biggest number of threads: 188 

और running = False लाइन को हटाने के द्वारा, मैं तो खोल में free -m आदेश का उपयोग कर मुक्त स्मृति को माप सकते हैं गणना क्यों मुझे पता है कि यह लगभग 8 एमबी प्रति थ्रेड ले रहा है, तब उपर्युक्त परीक्षण आवेदन से पहले और उसके दौरान उपयोग की गई स्मृति के अंतर को विभाजित करने से विभाजित करना सरल है जी, अधिकतम धागे से विभाजित यह शुरू करने में कामयाब रहे।

यह शायद केवल आवंटित स्मृति है, क्योंकि top पर देखकर, पायथन प्रक्रिया केवल 0.6% स्मृति का उपयोग करती है।

+0

स्मृति क्या ले रहा है? मैं अनुमान लगाता हूं कि यह वह डेटा है जिसे आप साइट से निकाल रहे हैं। यदि ऐसा है, तो शायद ऐसा नहीं है कि आप निष्पादन धागे की संख्या को थ्रॉटल करने से कम कर सकें। –

+0

आप मेमोरी उपयोग को बिल्कुल कैसे मापते हैं? मुझे लगता है कि, उन 8 एमबी वास्तव में प्रत्येक एकल धागे को आवंटित नहीं किया जाता है। उन 8 एमबी का एक बड़ा हिस्सा धागे के बीच साझा किया जा सकता है (बस एक अनुमान ..)? – Frunsi

+0

डेमियन और फ्रांसी, मैंने आपके दोनों सवालों के जवाब देने के लिए अपना प्रश्न संपादित किया। धन्यवाद! – Gargauth

उत्तर

4
+0

यह। यदि संसाधन प्रबंधन एक मुद्दा है, तो बस एक थ्रेड पूल है और पूल सीमा को ट्यून करें। –

+0

धन्यवाद! ऐसा लगता है कि गेवेन्ट वह है जो मैं ढूंढ रहा हूं। – Gargauth

0

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

आप इसे भी ढूढ़ सकते हैं ताकि डेटा को पुनर्प्राप्त करने के बाद आपके पास थ्रेड पूल ए के साथ एन थ्रेड्स को पिंग कर दिया जा सके, डेटा को क्रंच करने वाले वाई धागे के साथ डेटा को थ्रेड पूल बी में सौंप दें।

2

"प्रति थ्रेड प्रति अनुरोध" का उपयोग करना ठीक है और कई उपयोग-मामलों के लिए आसान है। हालांकि, इसके लिए बहुत सारे संसाधनों की आवश्यकता होगी (जैसा आपने अनुभव किया)।

एक बेहतर दृष्टिकोण एक asynchronuous एक का उपयोग करने के लिए है, लेकिन दुर्भाग्य से यह एक बहुत अधिक जटिल है।

इस दिशा में कुछ संकेत:

+0

धन्यवाद, बहुत सराहना की। मैंने पहले मुड़ने के बारे में पढ़ा, लेकिन दुख की बात है कि मैं इसके बारे में ज्यादा नहीं जानता और इसके बारे में मैं इसके साथ मशीनीकरण का उपयोग नहीं कर पाऊंगा। अगर मैं एसिंककोर के साथ मैकेनाइजेशन काम कर सकता हूं तो मैं एक नज़र डालूंगा। – Gargauth

+0

आखिरकार, एक "सही" समाधान थ्रेड पूल का मिश्रण होगा जिसमें एक थ्रेड प्रति सीपीयू कोर (प्रोसेसिंग कार्यों के लिए उनका उपयोग करने के लिए) और असीमित आईओ। एक व्यावहारिक समाधान आपके वास्तविक एप्लिकेशन कोड पर निर्भर करेगा। शायद, 'चयन' के आधार पर भी एक साधारण समाधान यह आपके लिए करेगा। – Frunsi

+1

इसका मतलब है: अपने धागे में: अनुरोधों का एक समूह भेजें, फिर एक लूप दर्ज करें जो उपयुक्त सॉकेट पर 'चयन करें' होगा, और किसी भी आने वाले डेटा को एक-एक करके संभालेगा ... और इसी तरह। आखिरकार, ओएस को सॉकेट आईओ के बारे में परवाह है, आपका काम ओएस के साथ सबसे प्रभावी तरीके से इंटरफ़ेस करना है। – Frunsi

1

समाधान इस तरह कोड को बदलने के लिए है ।
2) कुछ होने की प्रतीक्षा करें।
3) कुछ और करें।

इस तरह कोड के साथ:

1) कुछ करो।
2) इसे व्यवस्थित करें ताकि जब कुछ होता है, तो कुछ और किया जाता है।
3) हो गया।

कहीं और, आप कुछ धागे कि ऐसा करने के लिए है:

1) होने के लिए कुछ भी करने के लिए प्रतीक्षा करें।
2) जो भी हुआ वह संभाल लें।
3) चरण 1 पर जाएं।

पहले मामले में, यदि आप 50 चीजों के होने का इंतजार कर रहे हैं, तो आपके पास 50 चीजें होने के इंतजार में बैठे 50 धागे हैं। दूसरे मामले में, आपके पास एक थ्रेड इंतजार कर रहा है जो उस 50 चीजों में से किसी भी चीज को करने की ज़रूरत है।

तो, एक चीज का इंतजार करने के लिए थ्रेड का उपयोग न करें। इसके बजाए, इसे व्यवस्थित करें ताकि जब वह चीज होती है, तो कुछ अन्य थ्रेड जो कुछ भी करने की ज़रूरत है, करेंगे।

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