erreur: impossible de démarrer un nouveau fil
J'ai un site qui tourne avec un suivi de configuration:
Django + mod_wsgi + apache
Dans l'une de demande de l'utilisateur, j'ai envoyer une autre requête HTTP vers un autre service, et de le résoudre en httplib bibliothèque de python.
Mais parfois, ce service n'obtenez pas de réponse trop long, et le délai d'expiration pour httplib ne fonctionne pas. J'ai donc la création d'un thread, dans ce fil, j'ai envoyer une demande de service, et de le joindre au bout de 20 sec (20 sec - est un délai d'attente de la demande). Voilà comment cela fonctionne:
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
quelque chose comme ça...
Et l'utilisation de cette fonction:
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')
Et tous fonctionne bien, mais parfois j'ai commencer à attraper cette exception:
error: can't start new thread
à la ligne de départ de la nouvelle thread:
getting.start()
et la prochaine et dernière ligne de traceback est
File "/usr/lib/python2.5/threading.py", line 440, in start
_start_new_thread(self.__bootstrap, ())
Et la réponse est: Ce qui est arrivé?
Merci pour tous, et désolé pour mon anglais pur. 🙂
source d'informationauteur Oduvan
Vous devez vous connecter pour publier un commentaire.
"Impossible de démarrer un nouveau thread" erreur presque certainement en raison du fait que vous avez déjà trop de threads d'exécution au sein de votre python processus, et en raison d'un plafond de ressources de certains type de la demande de création d'un nouveau thread est refusé.
Vous devriez probablement vous regardez le nombre de threads que vous êtes en train de créer le maximum, vous serez en mesure de créer sera déterminé par votre environnement, mais il devrait être dans l'ordre de la centaine au moins.
Il serait probablement une bonne idée de repenser votre architecture; vu que c'est en cours d'exécution asynchrone de toute façon, vous pourriez peut-être utiliser un pool de threads pour aller chercher des ressources à partir d'un autre site, au lieu de toujours commencer un thread pour chaque demande.
Une autre amélioration à prendre en compte est votre utilisation de Thread.rejoignez et du Fil.arrêter; ce serait peut être mieux réalisé par l'offre d'une valeur de délai d'expiration pour le constructeur de HTTPSConnection.
De départ est à plus de threads pour être pris en charge par votre système. Il y a une limite pour le nombre de threads qui peuvent être actifs pour un processus.
Votre application est à partir de fils plus vite que les fils sont en cours d'exécution à l'achèvement. Si vous avez besoin pour démarrer le nombre de threads que vous avez besoin de le faire d'une manière plus contrôlée, je voudrais suggérer à l'aide d'un pool de threads.
Je pense que la meilleure solution dans votre cas est de délai d'attente du socket au lieu de frai fil:
Vous pouvez également définir le mondial de délai d'expiration par défaut avec
socket.setdefaulttimeout()
fonction.Mise à jour: Voir les réponses aux Est-il possible de tuer un Thread en Python? question (il y en a plusieurs très instructif) de comprendre pourquoi.
Thread.__stop()
n'est pas arrêter de thread, mais plutôt de définir des indicateurs internes de sorte qu'il est considéré comme déjà arrêté.J'ai complètement réécrire le code de httplib à pycurl.
quelque chose comme ça.
Et je test maintenant. Merci à tous de vous pour vous aider.
Si vous liant à définir délai d'pourquoi n'utilisez-vous pas urllib2.