python - त्रुटि: नया थ्रेड प्रारंभ नहीं कर सकता




django multithreading (4)

मेरे पास ऐसी साइट है जो विन्यास का पालन करती है:

Django + mod-wsgi + अपाचे

उपयोगकर्ता के एक अनुरोध में, मैं एक और HTTP अनुरोध को एक अन्य सेवा भेजता हूं, और अजगर की लाइब्रेरी पुस्तकालय द्वारा इसे हल करता हूं।

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

class HttpGetTimeOut(threading.Thread):
    def __init__(self,**kwargs):
        self.config = kwargs
        self.resp_data = None
        self.exception = None
        super(HttpGetTimeOut,self).__init__()
    def run(self):

        h = httplib.HTTPSConnection(self.config['server'])
        h.connect()
        sended_data = self.config['sended_data']
        h.putrequest("POST", self.config['path'])
        h.putheader("Content-Length", str(len(sended_data)))
        h.putheader("Content-Type", 'text/xml; charset="utf-8"')
        if 'base_auth' in self.config:
            base64string = base64.encodestring('%s:%s' % self.config['base_auth'])[:-1]
            h.putheader("Authorization", "Basic %s" % base64string)
        h.endheaders()

        try:
            h.send(sended_data)
            self.resp_data = h.getresponse()
        except httplib.HTTPException,e:
            self.exception = e
        except Exception,e:
            self.exception = e

कुछ इस तरह...

और इसे इस फ़ंक्शन द्वारा प्रयोग करें:

getting = HttpGetTimeOut(**req_config)
getting.start()
getting.join(COOPERATION_TIMEOUT)
if getting.isAlive(): #maybe need some block
    getting._Thread__stop()
    raise ValueError('Timeout')
else:
    if getting.resp_data:
        r = getting.resp_data
    else:
        if getting.exception:
            raise ValueError('REquest Exception')
        else:
            raise ValueError('Undefined exception')

और सभी काम ठीक है, लेकिन कुछ समय बाद मैं इस अपवाद को पकड़ना शुरू करता हूं:

error: can't start new thread

नया धागा शुरू करने की रेखा पर:

getting.start()

और ट्रेसबैक की अगली और अंतिम पंक्ति है

File "/usr/lib/python2.5/threading.py", line 440, in start
    _start_new_thread(self.__bootstrap, ())

और जवाब है: क्या हो रहा है?

सभी के लिए धन्यवाद, और मेरे शुद्ध अंग्रेजी के लिए खेद है। :)


आप अपने सिस्टम द्वारा संभाला जा सकता है की तुलना में अधिक धागे शुरू कर रहे हैं। धागे की संख्या की एक सीमा होती है जो एक प्रक्रिया के लिए सक्रिय हो सकती है।

थ्रेडों को पूरा करने के लिए चलने से आपकी एप्लिकेशन थ्रेड्स तेज़ी से शुरू हो रही हैं यदि आपको कई थ्रेड्स शुरू करने की आवश्यकता है तो आपको इसे अधिक नियंत्रित तरीके से करने की आवश्यकता होगी, मैं एक थ्रेड पूल का उपयोग करने का सुझाव दूंगा।


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

आपको संभवतः उन थ्रेड्स की संख्या देखना चाहिए जिन्हें आप बना रहे हैं; अधिकतम संख्या जो आप बनाने में सक्षम होंगे, आपके पर्यावरण द्वारा निर्धारित की जाएगी, लेकिन यह कम से कम सैकड़ों के क्रम में होना चाहिए

यह संभवतः आपके आर्किटेक्चर को फिर से सोचने के लिए एक अच्छा विचार होगा; क्योंकि यह अतुल्यकालिक रूप से किसी भी तरह से चल रहा है, शायद आप प्रत्येक अनुरोध के लिए एक धागा शुरू करने के बजाय किसी अन्य साइट से संसाधनों को लाने के लिए धागे के पूल का उपयोग कर सकते हैं

विचार करने के लिए एक अन्य सुधार थ्रेड का उपयोग है .जोइंड और थ्रेड.स्टॉप; यह संभवतः HTTPSConnection के निर्माता को टाइमआउट मान प्रदान करके बेहतर होगा।


मैं सर्कलप्लिब से पिकुरल तक पूरी तरह से कोड को फिर से लिखता हूं।

c = pycurl.Curl()
c.setopt(pycurl.FOLLOWLOCATION, 1)
c.setopt(pycurl.MAXREDIRS, 5)
c.setopt(pycurl.CONNECTTIMEOUT, CONNECTION_TIMEOUT)
c.setopt(pycurl.TIMEOUT, COOPERATION_TIMEOUT)
c.setopt(pycurl.NOSIGNAL, 1)
c.setopt(pycurl.POST, 1)
c.setopt(pycurl.SSL_VERIFYHOST, 0)
c.setopt(pycurl.SSL_VERIFYPEER, 0)
c.setopt(pycurl.URL, "https://"+server+path)
c.setopt(pycurl.POSTFIELDS,sended_data)

b = StringIO.StringIO()
c.setopt(pycurl.WRITEFUNCTION, b.write)

c.perform()

ऐसा कुछ।

और अब मैं इसका परीक्षण कर रहा हूं मदद के लिए आप सभी को धन्यवाद


यदि आप टाइमआउट सेट करना चाहते हैं तो आप urllib2 का उपयोग क्यों नहीं करते हैं







httplib