Python 多线程。线程中的异常

Python 多线程。线程中的异常,python,multithreading,exception,Python,Multithreading,Exception,我试着用一个简单的句子来理解。代码如下: 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()

我试着用一个简单的句子来理解。代码如下:

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()

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):
        while True:
            #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()

class DatamineThread(threading.Thread):
    """Threaded Url Grab"""
    def __init__(self, out_queue):
        threading.Thread.__init__(self)
        self.out_queue = out_queue

    def run(self):
        while True:
            #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()

start = time.time()
def main():

    #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()

main()
print "Elapsed Time: %s" % (time.time() - start)
有时我会在这里遇到这样的错误:

线程thread-10中出现异常(很可能在解释器关闭期间引发)

请解释原因

由其他作者更新:

下面是我在类似代码中看到的完全例外:

Exception in thread Thread-1 (most likely raised during interpreter shutdown):
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/threading.py", line 552, in __bootstrap_inner
  File "/usr/local/lib/python2.7/threading.py", line 505, in run
  File "mine.py", line 86, in run
  File "/usr/local/lib/python2.7/Queue.py", line 168, in get
  File "/usr/local/lib/python2.7/threading.py", line 237, in wait
<type 'exceptions.TypeError'>: 'NoneType' object is not callable
线程thread-1中的异常(很可能在解释器关闭期间引发): 回溯(最近一次呼叫最后一次): 文件“/usr/local/lib/python2.7/threading.py”,第552行,在引导程序内部 文件“/usr/local/lib/python2.7/threading.py”,第505行,运行中 文件“mine.py”,第86行,在运行中 get中的文件“/usr/local/lib/python2.7/Queue.py”,第168行 文件“/usr/local/lib/python2.7/threading.py”,第237行,正在等待 :“非类型”对象不可调用
您的示例脚本似乎还可以——也就是说,它在使用python 2.7.2时运行良好

您使用的是什么版本的python?您看到的错误可能与此有关。如果是这样,那么升级到python>=2.6.5或python>=3.1可能会有所帮助。

这就是bug

最简单的解决方法是添加超时

time.sleep(1)

在脚本结束时,允许线程在脚本结束前完成并结束

一些想法,人们可能更愿意帮助您:1。解释您为诊断问题所做的工作以及您的努力失败的原因。2.尝试将代码减少到发生错误所需的最小值。3.给出错误的完整回溯。我在类似的代码中看到了相同的错误。我将在上面添加我的完整异常。我在使用multiprocessing.Pool类时偶尔会发现此错误。它似乎来自于它创建的守护进程线程,当解释器在关机期间开始删除东西时,该线程仍在运行。一个解决方案,如果它没有解决这个问题,它会将频率降低到我的观察阈值以下,就是在完成多重处理时调用pool.terminate()或类似的方法。我在python 2.7中遇到了一个类似的问题:thread-9429中的异常:Traceback(最近的调用last):File“/Library/Frameworks/EPD64.framework/Versions/7.2/lib/python2.7/threading.py”,运行self.function(*self.args,**self.kwargs)中的第552行,在/Library/Frameworks/EPD64.framework/Versions/7.2/lib/python2.7/threading.py,第756行TypeError:“NoneType”对象不可调用或更好,请跟踪所有已启动的线程,并对其调用
t.join()
,以确保它们已正确退出并已清理。