一尘不染

错误:无法启动新线程

django

我有一个运行以下配置的网站:

Django + mod-wsgi + Apache

在一个用户的请求中,我向另一个服务发送另一个HTTP请求,并通过python的httplib库解决了这个问题。

但是有时此服务不会得到太长的答案,并且httplib的超时不起作用。因此,我创建了线程,在该线程中,我向服务发送请求,并在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, ())

答案是:发生了什么?


阅读 597

收藏
2020-03-31

共1个答案

一尘不染

几乎可以肯定,“无法启动新线程”错误是由于你的python进程中已经运行了太多线程,并且由于某种资源限制,创建新线程的请求被拒绝。

你可能应该看一下正在创建的线程数。你可以创建的最大数量取决于你的环境,但至少应在数百个数量级。

在这里重新考虑你的体系结构可能是一个好主意。看到它无论如何都是异步运行的,也许你可​​以使用线程池从另一个站点获取资源,而不是总是为每个请求启动线程。

要考虑的另一个改进是你对Thread.join和Thread.stop的使用。通过向HTTPSConnection的构造函数提供超时值,可能会更好地实现这一点。

2020-03-31