2010-11-01 10 views
14

J'ai un fil qui prolonge le filetage. Le code ressemble un peu à ceci;Python - vérification d'un fil/suppression de la liste

class MyThread(Thread): 
    def run(self): 
     # Do stuff 

my_threads = [] 
while has_jobs() and len(my_threads) < 5: 
    new_thread = MyThread(next_job_details()) 
    new_thread.run() 
    my_threads.append(new_thread) 

for my_thread in my_threads 
    my_thread.join() 
    # Do stuff 

Voici donc dans mon code pseudo Je vérifie pour voir s'il y a des emplois (comme un db etc) et s'il y a des emplois, et s'il y a moins de 5 threads en cours d'exécution, créer de nouveaux threads. Donc, à partir de là, je vérifie mes threads et c'est là où je suis coincé, je peux utiliser .join() mais je crois comprendre - cela attend alors qu'il soit terminé, donc si le premier thread qu'il vérifie est encore en cours, il attend alors que cela soit fait - même si les autres threads sont terminés ...

alors existe-t-il un moyen de vérifier si un thread est fait, puis retirez-le si oui?

par exemple

for my_thread in my_threads: 
    if my_thread.done(): 
     # process results 
     del (my_threads[my_thread]) ?? will that work... 

Répondre

24

Comme le dit TokenMacGuy, vous devez utiliser thread.isAlive() pour vérifier si un thread est toujours en cours. Pour supprimer plus threads en cours d'exécution de votre liste, vous pouvez utiliser un list comprehension:

for t in my_threads: 
    if not t.isAlive(): 
     # get results from thtead 
     t.handled = True 
my_threads = [t for t in my_threads if not t.handled] 

Cela évite le problème de la suppression d'éléments d'une liste en itérer dessus.

+0

Merci, mais est-ce que cela signifie qu'un résultat pourrait être perdu? Si un thread n'est plus vivant alors j'ai besoin d'obtenir les résultats. – Wizzard

+0

C'est vrai. J'ai modifié ma réponse pour en tenir compte. – Arlaharen

+5

'is_alive()' en Python 2.6+ – trim

4

Une meilleure façon est d'utiliser la classe File d'attente: http://docs.python.org/library/queue.html

Regardez le code bon exemple en bas de la page de la documentation:

def worker(): 
    while True: 
     item = q.get() 
     do_work(item) 
     q.task_done() 

q = Queue() 
for i in range(num_worker_threads): 
    t = Thread(target=worker) 
    t.daemon = True 
    t.start() 

for item in source(): 
    q.put(item) 

q.join()  # block until all tasks are done 
+1

Merci, mais puis-je rencontrer le même problème avec q.join()? si j'ai 20 emplois à faire mais que je veux seulement en faire 4 au maximum à la fois. Si 3 sont terminés et que l'un n'est pas terminé, je ne veux pas ralentir le programme tant qu'il attend ce résultat ... – Wizzard

0

La réponse a été couvert, mais pour la simplicité ...

# To filter out finished threads 
threads = [t for t in threads if t.is_alive()] 

# Same thing but for QThreads (if you are using PyQt) 
threads = [t for t in threads if t.isRunning()]