2012-07-18 113 views
1

我在使用python编写网站蜘蛛时遇到了麻烦。基本思想如下:Python线程池问题

我有一个队列,每个线程从队列中获取一个url并调用函数getAllLinks来获取来自该url的链接。伪代码如下:

class Spider(Threading.Thread): 
    def __init__(self): 
     self.queue = Queue.Queue 

    def run(self): 
     while True: 
      url = self.queue.get() 
      getAllLinks(url) 
      time.sleep(0.1) #I try to release the GIL 

但问题是:即使我打电话getAllLinks后手动切换线程,程序是不一样快单线程之一。有没有更好的办法?我想用多线程来提高蜘蛛的处理速度,但我认为time.sleep()比较慢,因为我强制一个线程释放GIL。

我认为这与for url in urlList: spider(url)类似。是不是只在getAllLinks()之后切换线程,基本上和只使用一个线程一样?

+0

'time.sleep()'语句的用途是什么?显然这会引入延迟,但是大概你有一个原因? – redrah 2012-07-18 13:01:10

+0

我不明白问题是什么,你能重申它吗? – interjay 2012-07-18 13:01:58

+0

因此,基本上,当您使用多个线程运行解决方案时,速度不如在单个线程上运行速度快吗?并且您希望提出有关如何使多线程工作以提高此应用程序速度性能的建议?请澄清。 – selllikesybok 2012-07-18 13:09:55

回答

0

所以,你的多线程程序并不比它的单线程版本快很多。

你是对的,CPython解释器将释放全局解释器锁(GIL)every 100 byte codes。不幸的是,GIL使不大量使用我的多线程程序/ O没用:

是否GIL阻止那些谁是纯Python从真正采取多核心的优势劳动人民?简单地说:是的,它的确如此。虽然线程本身是一种语言结构,但解释器是线程与OS之间映射的守门人。 (source)。

但是,你说你正在广泛使用I/O。 GIL在I/O完成时发布,这意味着您的程序可能会使用多线程来看的速度结果。

因此,将代码发布到getAllLinks函数!这样我们就可以测试什么在工作,什么不在工作。而且,虽然你可以使用time.sleep(.0001)来欺骗GIL进行释放(使用比0.1更小的数字),但由于你使用了大量的I/O,所以你不需要这种攻击。删除该行。

+0

的geAllLinks代码如下: DEF getAllLinks(URL): \t进口的urllib2为的urllib \t袜子=了urllib.urlopen(URL) \t htmlCode = sock.read() \t .... \t短袜.close() – lu4nx 2012-07-19 05:12:26

+0

为什么你要在每个Spider类中创建一个新的Queue.Queue? – ash 2012-07-19 18:43:00