代码之家  ›  专栏  ›  技术社区  ›  Kiv

如何在python中执行非阻塞URL获取

  •  2
  • Kiv  · 技术社区  · 16 年前

    我正在编写一个GUI应用程序 Pyglet 它必须显示数十到数百个来自互联网的缩略图。现在,我正在使用 urllib.urlretrieve 要抓住它们,但每次都要阻塞,直到它们完成,并且每次只能抓住一个。

    我更喜欢并行下载它们,并在完成后立即显示每一个,而不需要在任何时候阻塞GUI。最好的方法是什么?

    我对线程不太了解,但它看起来像 threading 模块可能有帮助?或者也许我忽略了一些简单的方法。

    6 回复  |  直到 11 年前
        1
  •  3
  •   drdaeman    16 年前

    你可能会从中受益 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)
    
        2
  •  2
  •   Richard Simões    16 年前

    正如您所怀疑的,这是线程处理的理想情况。 Here 这是一个简短的指南,当我在Python中执行自己的第一个线程时,我发现它非常有用。

        3
  •  2
  •   Brandon E Taylor    16 年前

    正如您正确指出的,您可以创建多个线程,每个线程负责执行urlretrieve操作。这允许主线程继续不间断地运行。

    下面是关于Python中线程的教程: http://heather.cs.ucdavis.edu/~matloff/Python/PyThreads.pdf

        4
  •  2
  •   Sean    16 年前

    下面是一个如何使用threading.thread的示例。只需用自己的类名替换类名,用自己的函数替换run函数。请注意,线程对于像您这样的限制IO的应用程序是非常好的,并且可以真正加快速度。在标准的python中严格使用pythong线程进行计算没有帮助,因为一次只能计算一个线程。

    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
    
        5
  •  1
  •   Unknown    16 年前

    您有以下选择:

    • 线程:最简单,但不能很好地扩展
    • 扭曲:中等难度,缩放良好,但由于gil和单线程共享CPU。
    • 多处理:最难。如果您知道如何编写自己的事件循环,那么可以很好地进行缩放。

    我建议您只使用线程,除非您需要一个工业规模的回卷器。

        6
  •  0
  •   Marius Gedminas    16 年前

    您要么需要使用线程,要么使用异步网络库,例如 Twisted . 我怀疑在您的特定用例中使用线程可能更简单。