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, ())

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

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


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


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

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()

ऐसा कुछ।

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


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

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

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

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


मुझे लगता है कि आपके मामले में सबसे अच्छा तरीका स्पॉइंग थ्रेड के बजाय सॉकेट टाइमआउट सेट करना है:

h = httplib.HTTPSConnection(self.config['server'], 
                            timeout=self.config['timeout'])

इसके अलावा आप socket.setdefaulttimeout() फ़ंक्शन के साथ वैश्विक डिफ़ॉल्ट समयबाह्य सेट कर सकते हैं।

अपडेट : पायथन में थ्रेड को मारने का कोई तरीका क्या है? प्रश्न (इसमें काफी जानकारीपूर्ण है) समझने के लिए क्यों Thread.__stop() थ्रेड को समाप्त नहीं करता है, बल्कि आंतरिक ध्वज सेट करता है ताकि इसे पहले ही रोक दिया गया हो।





httplib