Python - проверка потока/удаление из списка

У меня есть поток, который расширяет Thread. Код выглядит примерно так:

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

Итак, здесь, в моем псевдокоде, я проверяю, есть ли какие-либо задания (например, db и т.д.), и если есть несколько заданий, и если работает менее 5 потоков, создайте новые потоки.

Итак, теперь я просматриваю свои потоки, и вот где я застрял, я могу использовать .join(), но я понимаю, что это значит, что это ждет, пока оно не закончится, поэтому если первый поток, который он проверяет, все еще находится в прогресс, тогда он ждет, пока это не будет сделано, даже если остальные потоки закончены....

так есть ли способ проверить, выполняется ли поток, а затем удалить его, если это так?

например,

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

Ответ 1

Как говорит TokenMacGuy, вы должны использовать thread.isAlive(), чтобы проверить, работает ли поток. Чтобы удалить больше не выполняемых потоков из списка, вы можете использовать список:

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]

Это позволяет избежать проблемы удаления элементов из списка, итерации по нему.

Ответ 2

Лучше использовать класс Queue: http://docs.python.org/library/queue.html

Посмотрите на хороший пример кода внизу страницы документации:

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

Ответ 3

вам нужно вызвать thread.isAlive(), чтобы узнать, работает ли поток еще