如何在Python中进行非阻塞的URL获取
我正在用 Pyglet 写一个图形界面应用,这个应用需要从网上显示几十到几百个缩略图。目前,我使用 urllib.urlretrieve 来下载这些缩略图,但这个方法每次都要等下载完成才能继续,而且一次只能下载一个。
我希望能同时下载多个缩略图,并且每个缩略图下载完成后就能立刻显示,而不会在任何时候阻塞图形界面。这样做的最佳方法是什么呢?
我对线程的知识不多,但我觉得 threading 模块可能会有帮助?或者也许还有其他简单的方法我没有想到。
6 个回答
2
这里有一个关于如何使用 threading.Thread 的例子。只需要把类名换成你自己的,运行的函数也换成你自己的就可以了。需要注意的是,线程在处理输入输出(IO)受限的应用时非常有效,可以大大加快速度。不过,如果你只是用 Python 的线程来进行计算,那就没什么帮助,因为在标准 Python 中一次只能有一个线程在进行计算。
import threading, time
class Ping(threading.Thread):
def __init__(self, multiple):
threading.Thread.__init__(self)
self.multiple = multiple
def run(self):
#sleeps 3 seconds then prints 'pong' x times
time.sleep(3)
printString = 'pong' * self.multiple
pingInstance = Ping(3)
pingInstance.start() #your run function will be called with the start function
print "pingInstance is alive? : %d" % pingInstance.isAlive() #will return True, or 1
print "Number of threads alive: %d" % threading.activeCount()
#main thread + class instance
time.sleep(3.5)
print "Number of threads alive: %d" % threading.activeCount()
print "pingInstance is alive?: %d" % pingInstance.isAlive()
#isAlive returns false when your thread reaches the end of it's run function.
#only main thread now
2
正如你所说的,你可以创建多个线程,每个线程负责执行urlretrieve操作。这样主线程就可以不受影响地继续运行。
这里有一个关于Python中线程的教程:http://heather.cs.ucdavis.edu/~matloff/Python/PyThreads.pdf
3
你可能会发现使用 threading
或者 multiprocessing
模块会对你有帮助。其实你不需要自己去创建那些基于 Thread
的类,有一种更简单的方法可以使用 Pool.map
:
from multiprocessing import Pool
def fetch_url(url):
# Fetch the URL contents and save it anywhere you need and
# return something meaningful (like filename or error code),
# if you wish.
...
pool = Pool(processes=4)
result = pool.map(f, image_url_list)