检查线程/从列表中删除

Wiz*_*ard 21 python multithreading list

我有一个扩展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
Run Code Online (Sandbox Code Playgroud)

所以在我的伪代码中,我检查是否有任何作业(如数据库等),如果有一些作业,如果运行的线程少于5个,则创建新线程.

所以从这里,我检查我的线程,这是我卡住的地方,我可以使用.join()但我的理解是 - 然后等待它完成所以如果它检查的第一个线程仍在进行中,它然后等待直到完成 - 即使其他线程已完成....

那么有没有办法检查线程是否完成,然后删除它,如果是这样的话?

例如

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

Arl*_*ren 43

正如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]
Run Code Online (Sandbox Code Playgroud)

这避免了在迭代时从列表中删除项目的问题.

  • Python 2.6+中的`is_alive()` (11认同)

小智 8

mythreads = threading.enumerate()
Run Code Online (Sandbox Code Playgroud)

Enumerate 返回所有仍然存活的 Thread 对象的列表。 https://docs.python.org/3.6/library/threading.html


Dre*_*Dre 7

答案已经涵盖,但为简单起见......

# 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()]
Run Code Online (Sandbox Code Playgroud)


ser*_*yPS 6

更好的方法是使用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
Run Code Online (Sandbox Code Playgroud)


Sin*_*ion 5

您需要调用thread.isAlive()以查明线程是否仍在运行

  • `thread.isAlive()` 现已弃用,请使用 `thread.is_alive()` 代替。 (4认同)