[英]Python closing multiple Threads
我正在使用下面来自IBM网站的示例。 我注意到由于while循环,DatamineThread()和ThreadUrl()的线程保持打开状态。
我正在尝试终止这些线程并打印告诉我的内容。 我不确定是否要以正确的方式进行操作,或者不确定是否需要以这种方式终止线程。 问题是,当我在main()中将run设置为False时,while循环正在读取run = True。
任何帮助将是巨大的...谢谢
import Queue
import threading
import urllib2
import time
from BeautifulSoup import BeautifulSoup
hosts = ["http://yahoo.com", "http://google.com", "http://amazon.com",
"http://ibm.com", "http://apple.com"]
queue = Queue.Queue()
out_queue = Queue.Queue()
run = True
class ThreadUrl(threading.Thread):
"""Threaded Url Grab"""
def __init__(self, queue, out_queue):
threading.Thread.__init__(self)
self.queue = queue
self.out_queue = out_queue
def run(self):
global run
while run:
#grabs host from queue
host = self.queue.get()
#grabs urls of hosts and then grabs chunk of webpage
url = urllib2.urlopen(host)
chunk = url.read()
#place chunk into out queue
self.out_queue.put(chunk)
#signals to queue job is done
self.queue.task_done()
print 'ThreadUrl finished...'
class DatamineThread(threading.Thread):
"""Threaded Url Grab"""
def __init__(self, out_queue):
threading.Thread.__init__(self)
self.out_queue = out_queue
def run(self):
global run
while run:
#grabs host from queue
chunk = self.out_queue.get()
#parse the chunk
soup = BeautifulSoup(chunk)
print soup.findAll(['title'])
#signals to queue job is done
self.out_queue.task_done()
print 'DatamineThread finished...'
start = time.time()
def main():
global run
#spawn a pool of threads, and pass them queue instance
for i in range(5):
t = ThreadUrl(queue, out_queue)
t.setDaemon(True)
t.start()
#populate queue with data
for host in hosts:
queue.put(host)
for i in range(5):
dt = DatamineThread(out_queue)
dt.setDaemon(True)
dt.start()
#wait on the queue until everything has been processed
queue.join()
out_queue.join()
# try and break while-loops in threads
run = False
time.sleep(5)
main()
print "Elapsed Time: %s" % (time.time() - start)
我个人不是线程条件全局变量的忠实拥护者,很大程度上是因为我之前已经看过您遇到的情况。 原因来自Queue.get的python文档。
如果可选的args块为true,并且超时为None(默认值),则在必要时阻塞,直到有可用项为止。
本质上,您永远不会while run:
看到第二次检查while run:
因为out_queue.get()
在队列清空后无限期地阻塞。
更好的方法,恕我直言,要么在队列中使用哨兵值,要么使用get_nowait并捕获异常以打破循环。 例子:
class DatamineThread(threading.Thread):
def run(self):
while True:
data = self.out_queue.get()
if data == "time to quit": break
# non-sentinel processing here.
class DatamineThread(threading.Thread):
def run(self):
while True:
try:
data = self.out_queue.get_nowait() # also, out_queue.get(False)
except Queue.Empty: break
# data processing here.
为确保所有线程结束,可以采用以下几种方法:
for i in range(numWorkers):
out_queue.put('time to quit')
out_queue.join()
class DatamineThread(threading.Thread):
def run(self):
while True:
data = self.out_queue.get()
if data == "time to quit":
self.out_queue.put('time to quit')
break
# non-sentinel processing here.
两种方法都应该起作用。 首选哪种方式取决于out_queue的填充方式。 如果可以通过工作线程将其添加/删除,则首选第一种方法。 调用join()
,然后添加标记,然后再次调用join()
。 如果您不想记住您创建了多少个工作线程,则第二种方法很好-它仅使用一个哨兵值并且不会使队列混乱。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.