我在使用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 :(得分:0)
因此,您的多线程程序并不比单线程程序快得多。
你是正确的,因为CPython解释器将发布全局解释器锁(GIL),every 100 byte codes。不幸的是,GIL使多线程程序没有广泛使用I / O无用:
GIL是否会阻止那些使用纯Python的人真正利用多核?简单地说:是的,确实如此。虽然线程本身是一种语言结构,但解释器是线程和操作系统之间映射的守门员。 (source)。
但是,你说你正在广泛使用I / O. I / O完成时释放GIL,这意味着您的程序可以使用多线程查看速度结果。
所以,将代码发布到您的getAllLinks
函数中!通过这种方式,我们可以对哪些工作和什么不工作进行基准测试。而且,尽管你可以使用time.sleep(.0001)
来欺骗GIL(使用比0.1
更小的数字),因为你使用了很多I / O,你不应该需要这个hack。删除该行。