2010-09-06 65 views
1

我寫了一個簡單的webpool使用線程池。問題是:然後爬蟲遍佈整個網站它必須完成,但實際上它最終等待一些東西,並且腳本沒有完成,爲什麼會發生這種情況?python 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)後task.get(...)運行插入

if not func: break 

2)追加

pool.add_task(None, None, None) 

過程的結束。

這是進程通知他沒有更多任務要處理的方法。

+0

thanx,尋求幫助。我最終解決它,如果self.tasks.qsize()== 0: 中斷 – Evg 2010-09-06 12:12:08

+0

@Evg:小心,「任務隊列是空的」是不一樣的「沒有更多的工作要做」... – dugres 2010-09-06 12:43:32

+0

是的thnx再次)我明白這一點,這是一個問題。在你的情況下「在流程結束時」。我必須檢查空隊列,如果它爲空,請執行pool.add_task(None,None,None)。沒有「停止任務」的想法不會讓我活下去,我認爲exsist的標誌是 - 所有工人都有等待狀態(在func,args,kargs = self.tasks.get()之前的行) )。如果發生這種情況,我可以打破所有工人的所有循環,你對此有何看法? – Evg 2010-09-06 15:52:10