Многопоточность. Исключение в потоке

#python #multithreading #exception

#python #многопоточность #исключение

Вопрос:

Я пытаюсь понять на примере. Вот код:

 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
  

Комментарии:

1. Некоторые идеи, как люди могли бы быть более готовы помочь вам: 1. Объясните, что вы сделали для диагностики проблемы и почему ваши усилия не увенчались успехом. 2. Постарайтесь сократить код до минимума, необходимого для возникновения ошибки. 3. Укажите полную обратную трассировку ошибки.

2. Я вижу ту же ошибку в аналогичном коде. Я добавлю свое полное исключение выше.

3. Я иногда обнаруживаю эту ошибку, когда использую многопроцессорную обработку. Класс пула. Похоже, что из потоков демонов, которые он создает, все еще работают, когда интерпретатор начинает удалять вещи во время завершения работы. Решение, которое, если оно его не решило, уменьшило частоту ниже моего порога наблюдения, состоит в том, чтобы вызвать pool.terminate() или аналогичный, когда вы закончите с мультиобработкой.

Ответ №1:

Это ошибка http://bugs.python.org/issue14623

Самый простой обходной путь — добавить время ожидания

 time.sleep(1)
  

в конце скрипта, который позволяет потокам завершаться до того, как сценарий завершит жизнь и закроется

Комментарии:

1. Или, что еще лучше, отслеживайте все запущенные потоки и вызывайте t.join() их, чтобы убедиться, что они правильно завершены и очищены.

Ответ №2:

Ваш пример сценария кажется нормальным, то есть он отлично работает для меня, используя python 2.7.2.

Какую версию python вы используете? Возможно, ошибки, которые вы видите, могут быть связаны с этой ошибкой. Если это так, то может помочь обновление до python> = 2.6.5 или python> = 3.1.

Комментарии:

1. Я получаю аналогичную проблему с python 2.7: исключение в потоке Thread-9429: Трассировка (последний последний вызов): File «/Library/Frameworks/EPD64.framework/Versions/7.2/lib/python2.7/threading.py «, строка 552, в файле __bootstrap_inner self.run() «/Library/Frameworks/EPD64.framework/Versions/7.2/lib/python2.7/threading.py «, строка 756, в run self.function(*self.аргументы, ** self.kwargs) Ошибка типа: объект ‘NoneType’ не вызывается