队列中的所有任务均已完成,但程序未继续 - python

我有一个这样定义的线程类:

#!/usr/bin/python

import threading
import subprocess

class PingThread (threading.Thread):
    ipstatus = ''
    def __init__(self, ip):
        threading.Thread.__init__(self)
        self.ipaddress = ip


    def ping(self, ip):
        print 'Pinging ' + ip + '...'
        ping_response = subprocess.Popen(["ping", "-c", "1", ip], stdout=subprocess.PIPE).stdout.read()
        if '100.0% packet loss' not in str(ping_response):
            return True
        return False

    def set_ip_status(self, status):
        self.ipstatus = status

    def get_ip_status(self):
        return self.ipstatus

    def run(self):
        self.ipaddress = self.ipaddress.strip('\n\t')
        pingResponse = self.ping(self.ipaddress)
        if pingResponse:
            self.set_ip_status(self.ipaddress + ' is up!')
        else:
            self.set_ip_status(self.ipaddress + ' is down!')

我正在查看IP地址列表,并将其发送到PingThread,并让此类ping IP地址。这些线程全部完成后,我希望它通过调用get_ip_status()来获得每个线程的状态。我的代码中有q.join(),应该等到队列中的所有项目都完成后(据我了解,如果我错了,请更正我,仍然是线程新手),但是我的代码从未通过q.join 。我测试了所有线程,并完成了所有IP地址的ping操作,但是q.join()无法识别。为什么是这样?我究竟做错了什么?我正在创建这样的线程:

q = Queue.Queue()
for ip in trainips:
    thread = PingThread(ip)
    thread.start()
    q.put(thread)
q.join()
while not q.empty():
    print q.get().get_ip_status()

python大神给出的解决方案

您误解了Queue.join的工作原理。 Queue.join旨在与Queue.task_done一起使用;在生产者端,您将put个项目放入一端的Queue中,然后调用Queue.join以等待处理您所有put的项目。然后在消费者端,您从getQueue一个项目,对其进行处理,然后在完成后调用Queue.task_done。为所有已被task_done放入put的项目调用Queue后,Queue.join将解除阻止。

但是你没有那样做。您只是在启动一堆线程,将它们添加到Queue,然后在其上调用join。您根本不使用task_done,而只是在Queue.get之后调用Queue.join,看起来您只是在用它来完成线程对象。但这不是真的。 Queue不知道其中是否有Thread对象,只需调用Queue.join就不会等待其中的Thread对象完成。

确实,看起来您需要做的就是将线程放入列表中,然后在每个线程上调用join

threads = []
for ip in trainips:
    thread = PingThread(ip)
    thread.start()
    threads.append(thread)
for thread in threads:
    thread.join()
    print thread.get_ip_status()