Python Fils Accrocher
J'ai un simple filetée programme en Python suivant la norme paradigme:
class SearchThread(threading.Thread):
def __init__(self, search_queue):
threading.Thread.__init__(self)
self.search_queue = search_queue
def run(self):
while True:
try:
search_url = self.search_queue.get(timeout=15)
# <do Internet search and print output/>
except Queue.Empty:
self.search_queue.task_done()
break
except Exception, e:
print e
if __name__ == '__main__':
search_queue = Queue.Queue()
for i in range(200):
t = SearchThread(search_queue)
t.setDaemon(True)
t.start()
search_queue.join()
La file d'attente est rempli avec environ 1000 urls et simple HTTP GET
est effectuée dans <do Internet search and print output/>
. Le problème est que, après le traitement de certains de 500 à 700 entrées (qui ne prend que quelques secondes), le programme se bloque constamment pour toujours avec pas de sortie, pas d'exception, rien.
J'ai essayé requests
, urllib2
, urllib3
, httplib2
pour la HTTP GET
mais rien ne change.
Comment déboguer pendaison filetée programme en Python?
BTW, je suis à l'aide de Python 2.7 sous Ubuntu 11.10 (64bit).
modifier
Je suis aussi paumé qu'avant quand regarder le gdb trace sur le support de processus --
sudo gdb python 9602
GNU gdb (Ubuntu/Linaro 7.3-0ubuntu2) 7.3-2011.08
...
(gdb) where
#0 0x00007fc09ea91300 in sem_wait () from /lib/x86_64-linux-gnu/libpthread.so.0
#1 0x00000000004ed001 in PyThread_acquire_lock ()
#2 0x00000000004f02de in ?? ()
#3 0x00000000004b6569 in PyEval_EvalFrameEx ()
#4 0x00000000004bcd2d in PyEval_EvalCodeEx ()
#5 0x00000000004b6a5b in PyEval_EvalFrameEx ()
#6 0x00000000004b6d77 in PyEval_EvalFrameEx ()
#7 0x00000000004bcd2d in PyEval_EvalCodeEx ()
#8 0x00000000004bd802 in PyEval_EvalCode ()
#9 0x00000000004dcc22 in ?? ()
#10 0x00000000004dd7e4 in PyRun_FileExFlags ()
#11 0x00000000004de2ee in PyRun_SimpleFileExFlags ()
#12 0x00000000004ee6dd in Py_Main ()
#13 0x00007fc09d86030d in __libc_start_main () from /lib/x86_64-linux-gnu/libc.so.6
#14 0x000000000041cb69 in _start ()
essayez de suivre ce tutoriel
J'ai eu un problème similaire ici: stackoverflow.com/questions/28223414/...
OriginalL'auteur Jerry | 2012-04-04
Vous devez vous connecter pour publier un commentaire.
J'ai écrit un module qui permet d'afficher fils qui pendent plus de 10 secondes à un endroit.
hanging_threads.py (package)
Voici un exemple de sortie:
Cela se produit à la sortie du thread principal lorsque vous oubliez de définir un autre thread que daemon.
OriginalL'auteur User
semble que vous êtes confrontés à la même question, comme mentionné dans ce fil.
python multitraitement: certaines fonctions ne revient pas quand ils sont au complet (la file d'attente le matériau est trop gros)
Point crucial est que c'est un non résolu/fermé bug? http://bugs.python.org/issue8237
OriginalL'auteur maneet
Je ne sais pas si vous avez encore le problème (la question est un peu vieux...).
Il ressemble à un classique de blocage (parce qu'elle semble s'accrocher à certains mutex lock).
Pour GDB, il existe quelques belles scripts Python qui peut rendre le C backtrace avec Python appelle plus instructif. I. e. il montre la réelle Python appels pour cela:
Je pense que ces GDB scripts Python sont même inclus dans l'original de la distribution Python. Les vérifier.
Puis, il y a le grand faulthandler module qui vous offre une fonction pour imprimer le Python backtrace (par exemple dans un gestionnaire de signal). Dans mon MusicPlayer projet, j'ai étendu un peu et je les utilise massivement pour le débogage.
Par exemple, j'ai ajouté cette fonction:
Et maintenant, quand je suis dans GDB ou LLDB et souhaitez connaître les threads Python, je viens de type
p _Py_DumpTracebackAllThreads()
et il est imprimé sur la sortie standard stdout.En plus de cela, vous êtes intéressé par le C trace de tous les threads en cours, c'est à dire
t apply all bt full
devrait imprimer toutes les backtraces dans GDB.Si c'est le Python GIL où il se bloque, il y a probablement certains autres actifs Python fil qui pend pour quelque chose d'autre. Qui est le véritable bug. Il devrait avoir libéré le Python GIL avant que.
OriginalL'auteur Albert
Votre tandis que la boucle est infinie. Le fil ne sera jamais fini de l'exécution, même lorsque la file d'attente est vide.Vous devez vérifier la file d'attente pour de nouvelles tâches ou de notifier une thread (à l'aide d'Événement par exemple) qu'aucune tâche n'est prévu.
En fait non. Voir mon post ci-dessous.
OriginalL'auteur Maksym Polshcha
Ce débogueur peut débogage multithread python programmes: http://winpdb.org/
OriginalL'auteur katzenversteher
Encore une autre chose est l'utilisation abusive de la File d'attente.obtenir. Le 1er argument est une valeur booléenne "en bloc".
Vous devriez écrire quelque chose comme:
Et, comme je l'ai écrit ci-dessus, évitez d'utiliser des boucles infinies. Lorsque votre délai d'attente expire, la File d'attente.obtenir soulève le "Vide", exception qui est visé par "sauf Exception" (encore une autre construction qui doit être évitée à l'utilisation). Si votre boucle est vraiment infini. Vous chat le changement "sauf Exception" pour
Modifier
Question initiale, le code est comme suit
J'ai couru votre code de mon côté, avec quelques modifications mineures: remplir la file d'attente et imprimez un élément après l'obtention de la file d'attente comme ci-dessous: ... search_url = auto.search_queue.get(timeout=15) impression search_url ... ... search_queue = File d'attente.La file d'attente (les) carte(search_queue.mettre, xrange(0,1000)) ... Le code fonctionne bien de mon côté. Le plus probable que le "blocage" causé par certains problèmes de réseau (si votre code ne certaines requêtes HTTP): l'insuffisance de la bande passante, inaccessible hôtes, les demandes problèmes de code etc.
Salut Maksym, je vous remercie pour votre aide. J'ai fait des tests similaires et a obtenu le même résultat: il ne se produit que quand il y a de l'activité réseau impliqués, bien que le problème ne jamais se manifeste lorsqu'il est exécuté en seul thread. Donc, je suis toujours désemparés quant à exactement pourquoi ou comment le résoudre.
Si vous me fournir vos opérations de réseau j'ai pu vous aider.
OriginalL'auteur Maksym Polshcha