web-dev-qa-db-fra.com

Vérification sur un fil / supprimer de la liste

J'ai un fil qui prolonge le fil. Le code ressemble un peu à ceci;

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

Donc, ici, dans mon pseudo-code, je vérifie s'il y a des travaux (comme une base de données, etc.) et s'il y a des travaux, et s'il y a moins de 5 threads en cours d'exécution, créez de nouveaux threads.

Donc à partir d'ici, je vérifie ensuite mes threads et c'est là que je suis bloqué, je peux utiliser .join () mais ma compréhension est que - cela attend ensuite jusqu'à ce qu'il soit terminé, donc si le premier thread qu'il vérifie est toujours en cours, il attend ensuite que cela soit fait - même si les autres threads sont terminés ....

existe-t-il un moyen de vérifier si un thread est terminé, puis de le supprimer si oui?

par exemple

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

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

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 supprimer des éléments d'une liste tout en itérant dessus.

39
Arlaharen

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

Regardez le bon exemple de code au bas de la page de 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
6
seriyPS

vous devez appeler thread.isAlive() pour savoir si le thread est toujours en cours d'exécution

mythreads = threading.enumerate()

Enumerate renvoie une liste de tous les objets Thread encore en vie. https://docs.python.org/3.6/library/threading.html

4
William DeCook

La réponse a été couverte, mais pour plus de 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()]
2
Dre