Comment Interrompre/Arrêt/Fin de un accrochage multi-thread programme en python
J'ai un programme en python qui implémente des fils comme ceci:
class Mythread(threading.Thread):
def __init__(self, name, q):
threading.Thread.__init__(self)
self.name = name
self.q = q
def run(self):
print "Starting %s..." % (self.name)
while True:
## Get data from queue
data = self.q.get()
## do_some_processing with data ###
process_data(data)
## Mark Queue item as done
self.q.task_done()
print "Exiting %s..." % (self.name)
def call_threaded_program():
##Setup the threads. Define threads,queue,locks
threads = []
q = Queue.Queue()
thread_count = n #some number
data_list = [] #some data list containing data
##Create Threads
for thread_id in range(1, thread_count+1):
thread_name = "Thread-" + str(thread_id)
thread = Mythread(thread_name,q)
thread.daemon = True
thread.start()
##Fill data in Queue
for data_item in data_list:
q.put(data_item)
try:
##Wait for queue to be exhausted and then exit main program
q.join()
except (KeyboardInterrupt, SystemExit) as e:
print "Interrupt Issued. Exiting Program with error state: %s"%(str(e))
exit(1)
La call_threaded_program() est appelée à partir d'un autre programme.
J'ai le code de travail dans des circonstances normales. Toutefois, si une erreur/exception se produit dans l'un des threads, alors le programme est bloqué (comme la file d'attente se joindre à l'infini de blocage). La seule façon que je suis en mesure d'arrêter de ce programme est de fermer le terminal lui-même.
Quelle est la meilleure façon de mettre fin à ce programme, lorsqu'un thread bails? Est-il propre (en fait je prendrais de toute façon) manière de procéder? Je sais que cette question a été posée de nombreuses fois, mais je suis toujours incapable de trouver une réponse convaincante. Je serais vraiment reconnaissant de toute aide.
EDIT:
J'ai essayé de supprimer la jointure sur la file d'attente et utilisé un réseau mondial de sortie drapeau comme suggéré dans Est-il possible de tuer un Thread en Python?
Cependant, aujourd'hui, le comportement est très étrange, je ne comprends pas ce qui se passe.
import threading
import Queue
import time
exit_flag = False
class Mythread (threading.Thread):
def __init__(self,name,q):
threading.Thread.__init__(self)
self.name = name
self.q = q
def run(self):
try:
# Start Thread
print "Starting %s...."%(self.name)
# Do Some Processing
while not exit_flag:
data = self.q.get()
print "%s processing %s"%(self.name,str(data))
self.q.task_done()
# Exit thread
print "Exiting %s..."%(self.name)
except Exception as e:
print "Exiting %s due to Error: %s"%(self.name,str(e))
def main():
global exit_flag
##Setup the threads. Define threads,queue,locks
threads = []
q = Queue.Queue()
thread_count = 20
data_list = range(1,50)
##Create Threads
for thread_id in range(1,thread_count+1):
thread_name = "Thread-" + str(thread_id)
thread = Mythread(thread_name,q)
thread.daemon = True
threads.append(thread)
thread.start()
##Fill data in Queue
for data_item in data_list:
q.put(data_item)
try:
##Wait for queue to be exhausted and then exit main program
while not q.empty():
pass
# Stop the threads
exit_flag = True
# Wait for threads to finish
print "Waiting for threads to finish..."
while threading.activeCount() > 1:
print "Active Threads:",threading.activeCount()
time.sleep(1)
pass
print "Finished Successfully"
except (KeyboardInterrupt, SystemExit) as e:
print "Interrupt Issued. Exiting Program with error state: %s"%(str(e))
if __name__ == '__main__':
main()
De sortie du programme est comme ci-dessous:
#Threads get started correctly
#The output also is getting processed but then towards the end, All i see are
Active Threads: 16
Active Threads: 16
Active Threads: 16...
Ensuite, le programme se bloque ou de garde sur l'impression des threads actifs. Cependant, depuis la sortie d'indicateur est défini à True, la méthode run du thread n'est pas exercé. Donc je n'ai aucune idée de la façon dont ces fils sont maintenus ou ce qui se passe.
MODIFIER:
J'ai trouvé le problème. Dans le code ci-dessus, le fil de la méthode get étaient blocage et donc pas en mesure de cesser de fumer. À l'aide d'une méthode get avec un délai d'attente au lieu de cela a fait le tour. J'ai le code pour l'exécution de la méthode que j'ai modifié ci-dessous
def run(self):
try:
#Start Thread
printing "Starting %s..."%(self.name)
#Do Some processing
while not exit_flag:
try:
data = self.q.get(True,self.timeout)
print "%s processing %s"%(self.name,str(data))
self.q.task_done()
except:
print "Queue Empty or Timeout Occurred. Try Again for %s"%(self.name)
# Exit thread
print "Exiting %s..."%(self.name)
except Exception as e:
print "Exiting %s due to Error: %s"%(self.name,str(e))
OriginalL'auteur NRS | 2013-05-22
Vous devez vous connecter pour publier un commentaire.
Si vous voulez forcer tous les fils à la sortie lorsque le processus s'arrête, vous pouvez définir le "démon" le drapeau du fil à Vrai avant que le thread est créé.
http://docs.python.org/2/library/threading.html#threading.Thread.daemon
OriginalL'auteur Michael R. Hines
Je l'ai fait une fois dans C. Fondamentalement, j'ai eu un processus principal qui commençaient les autres et traces conservées d'entre eux, c'est à dire. stocké le PID et attendu pour le code de retour. Si vous avez une erreur dans un processus le code de l'indiquer et ensuite, vous pouvez cesser de tous les autres processus. Espérons que cela aide
Edit:
Désolé je peux avoir oublié dans ma réponse que vous avez été à l'aide de threads. Mais je pense que ça s'applique toujours. Vous pouvez envelopper ou de modifier le thread pour obtenir une valeur de retour ou vous pouvez utiliser le multi thread pool bibliothèque.
comment obtenir la valeur de retour à partir d'un fil en python?
Python fil code de sortie
OriginalL'auteur seven-down