import threading
import Queue
import urllib2
import time
class ThreadURL(threading.Thread):
def __init__(self, queue):
threading.Thread.__init__(self)
self.queue = queue
def run(self):
while True:
host = self.queue.get()
sock = urllib2.urlopen(host)
data = sock.read()
self.queue.task_done()
hosts = ['http://www.google.com', 'http://www.yahoo.com', 'http://www.facebook.com', 'http://stackoverflow.com']
start = time.time()
def main():
queue = Queue.Queue()
for i in range(len(hosts)):
t = ThreadURL(queue)
t.start()
for host in hosts:
queue.put(host)
queue.join()
if __name__ == '__main__':
main()
print 'Elapsed time: {0}'.format(time.time() - start)
我一直在努力探索如何执行线程,经过一些教程后,我想出了上述内容。
它应该做的是:
我首先想知道的是,我这样做是否正确?这是处理线程的最佳方法吗?
其次,我的程序无法退出。它打印出Elapsed time
行,然后挂起。我必须杀死我的终端才能离开。我假设这是由于我错误地使用了queue.join()
?
答案 0 :(得分:7)
您的代码看起来很好并且很干净。
您的应用程序仍然“挂起”的原因是工作线程仍在运行,等待主应用程序将某些内容放入队列中,即使您的主线程已完成。
解决此问题的最简单方法是在调用start之前执行t.daemon = True
将线程标记为后台进程。这样,线程就不会阻止程序停止。
答案 1 :(得分:2)
看起来很好。 yann关于守护进程的建议是正确的。这将解决你的问题。我唯一的问题是为什么要使用队列?您没有进行任何跨线程通信,因此您似乎可以将主机信息作为arg发送到ThreadURL init()并删除队列。
它没有错,只是想知道。
答案 2 :(得分:2)
有一件事,在线程运行函数中,while True循环,如果发生了一些异常,则可能不会调用task_done(),但是已经调用了get()。因此queue.join()可能永远不会结束。