1

我在使用 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(),本质上与仅使用一个线程相同吗?

4

1 回答 1

0

因此,您的多线程程序并不比它的单线程版本快得多。

您是正确的,CPython 解释器将释放全局解释器锁 (GIL),每 100 字节代码。不幸的是,GIL 使不广泛使用 I/O 的多线程程序变得毫无用处:

GIL 是否会阻止那些使用纯 Python 工作的人真正利用多核?简单地说:是的,确实如此。虽然线程本身是一种语言结构,但解释器是线程和操作系统之间映射的看门人。(来源)。

但是,您说您正在广泛使用 I/O。GIL 在 I/O 完成时被释放,这意味着您的程序可以看到使用多线程的速度结果。

因此,将代码发布到您的getAllLinks函数中!通过这种方式,我们可以对哪些有效,哪些无效。而且,尽管您可以time.sleep(.0001)用来诱使 GIL 释放(使用比 更小的数字0.1),但由于您使用了大量的 I/O,您不应该需要这个 hack。删除该行。

于 2012-07-18T17:15:49.747 回答