2010-11-01 11 views
14

Tengo un hilo que extiende el hilo. El código se ve un poco así;Python - comprobar en un hilo/eliminar de la lista

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 

Así que aquí en mi código de pseudo puedo comprobar para ver si hay cualquier trabajo (como una base de datos, etc.) y si hay algunos puestos de trabajo, y si hay menos de 5 hilos de ejecución, crear nuevos temas.

Así que desde aquí, compruebo mis hilos y aquí es donde me quedo atascado, puedo usar .join() pero mi entendimiento es que - esto espera hasta que se termine así que si el primer hilo que revisa sigue siendo en progreso, luego espera hasta que finalice, incluso si los otros hilos están terminados ...

así que, ¿hay alguna manera de verificar si un hilo está hecho, y luego eliminarlo si es así?

por ejemplo

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

Respuesta

24

Como TokenMacGuy dice, se debe utilizar thread.isAlive() para comprobar si un hilo sigue corriendo. Para quitar las discusiones ya no se ejecutan de su lista se puede utilizar 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] 

Esto evita el problema de la eliminación de elementos de una lista, mientras que la iteración sobre ella.

+0

Gracias, pero ¿eso significa que se podría perder un resultado? Si un hilo ya no está Vivo, entonces necesito obtener los resultados. – Wizzard

+0

Eso es verdad. He modificado mi respuesta para tener esto en cuenta. – Arlaharen

+5

'is_alive()' en Python 2.6+ – trim

4

mejor forma de hacerlo es utilizar la clase de cola: http://docs.python.org/library/queue.html

Mira el buen ejemplo de código en la parte inferior de la página de documentación:

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

Gracias, pero ¿puedo encontrar el mismo problema con q.join()? si tengo 20 trabajos que necesitan hacerlo, pero solo quiero ejecutar como máximo 4 por vez. Si 3 están hechos y uno no está terminado, entonces no quiero ralentizar el programa mientras espera ese 1 resultado ... – Wizzard

0

La respuesta ha sido cubierto, pero por simplicidad ...

# 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()] 
Cuestiones relacionadas