проблема Python Threadpool (ждать чего-то) - PullRequest
1 голос
/ 06 сентября 2010

Я написал простой веб-сайт Crowler с Threadpool. Проблема в том, что тогда сканер должен пройти весь сайт, который он должен завершить, но в действительности он ждет чего-то в конце, а сценарий не завершен, почему это произошло?

from Queue import Queue
from threading import Thread

import sys
from urllib import urlopen
from BeautifulSoup import BeautifulSoup, SoupStrainer
import re
from Queue import Queue, Empty
from threading import Thread

visited = set()
queue = Queue()

class Worker(Thread):
    """Thread executing tasks from a given tasks queue"""
    def __init__(self, tasks):
        Thread.__init__(self)
        self.tasks = tasks
        self.daemon = True
        self.start()

    def run(self):
        while True:
            func, args, kargs = self.tasks.get()
            print "startcall in thread",self
            print args
            try: func(*args, **kargs)
            except Exception, e: print e
            print "stopcall in thread",self
            self.tasks.task_done()

class ThreadPool:
    """Pool of threads consuming tasks from a queue"""
    def __init__(self, num_threads):
        self.tasks = Queue(num_threads)
        for _ in range(num_threads): Worker(self.tasks)

    def add_task(self, func, *args, **kargs):
        """Add a task to the queue"""
        self.tasks.put((func, args, kargs))

    def wait_completion(self):
        """Wait for completion of all the tasks in the queue"""
        self.tasks.join()


def process(pool,host,url):

    try:
        print "get url",url
        #content = urlopen(url).read().decode(charset)
        content = urlopen(url).read()
    except UnicodeDecodeError:
        return

    for link in BeautifulSoup(content, parseOnlyThese=SoupStrainer('a')):
        #print "link",link
        try:
            href = link['href']
        except KeyError:
            continue


        if not href.startswith('http://'):
            href = 'http://%s%s' % (host, href)
        if not href.startswith('http://%s%s' % (host, '/')):
            continue



        if href not in visited:
            visited.add(href)
            pool.add_task(process,pool,host,href)
            print href




def start(host,charset):

    pool = ThreadPool(7)
    pool.add_task(process,pool,host,'http://%s/' % (host))
    pool.wait_completion()

start('simplesite.com','utf8') 

1 Ответ

1 голос
/ 06 сентября 2010

Проблема, которую я вижу, заключается в том, что вы никогда не выходите из , пока в запускаете . Таким образом, он будет блокировать навсегда. Вам нужно разорвать этот цикл, когда работа будет завершена.

Вы можете попробовать:
1) вставить

if not func: break  

после task.get (...) в run .

2) append

pool.add_task(None, None, None)  

в конце процесса .

Это способ процесса уведомить пул , что у него больше нет задачи для обработки.

...