【问题标题】:python threadpool problem (wait for something)python线程池问题(等等)
【发布时间】:2010-09-06 02:57:54
【问题描述】:

我用线程池编写了简单的网站爬虫。问题是:然后爬虫爬满整个站点,它必须完成,但实际上它最终会等待一些东西,并且脚本没有完成,为什么会发生这种情况?

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

【问题讨论】:

    标签: python multithreading pool


    【解决方案1】:

    我看到的问题是您永远不会在 run 中退出 while。因此,它将永远阻塞。工作完成后,你需要打破这个循环。

    你可以试试:
    1) 插入

    if not func: break  
    

    运行中的task.get(...)之后。

    2) 追加

    pool.add_task(None, None, None)  
    

    进程结束时。

    这是 process 通知 pool 他没有更多任务要处理的一种方式。

    【讨论】:

    • 谢谢,寻求帮助。我终于用 if self.tasks.qsize() == 0: break 解决了
    • @Evg :小心,“任务队列为空”与“没有更多工作要做”......
    • yes thnx 再次)我明白这一点,这是一个问题。在您的情况下,“在流程结束时”。我必须检查队列是否为空,如果它为空,请执行 pool.add_task(无,无,无)。没有“停止任务”的想法不要让我住,我认为存在的标志是 - 所有工人都有等待状态(func,args,kargs = self.tasks.get() 之前的行)。如果发生这种情况,我可以打破所有工人的所有循环,你怎么看?
    • ..我认为退出标志是..
    • 我在这里提出了实施的新问题 - stackoverflow.com/questions/3653675/…
    猜你喜欢
    • 1970-01-01
    • 2015-08-29
    • 2010-10-16
    • 1970-01-01
    • 2015-07-13
    • 2014-06-20
    • 2020-10-02
    • 1970-01-01
    相关资源
    最近更新 更多