【问题标题】:request.urlretrieve in multiprocessing Python gets stuck多处理 Python 中的 request.urlretrieve 卡住了
【发布时间】:2018-02-28 05:09:56
【问题描述】:

我正在尝试使用 Python 从 URL 列表中下载图像。为了加快处理速度,我使用了多处理库。

我面临的问题是脚本经常自行挂起/冻结,我不知道为什么。

这是我正在使用的代码

...
import multiprocessing as mp

def getImages(val):

    #Dowload images
    try:
        url= # preprocess the url from the input val
        local= #Filename Generation From Global Varables And Rand Stuffs...
        urllib.request.urlretrieve(url,local)
        print("DONE - " + url)
        return 1
    except Exception as e:
        print("CAN'T DOWNLOAD - " + url )
        return 0

if __name__ == '__main__':

    files = "urls.txt"
    lst = list(open(files))
    lst = [l.replace("\n", "") for l in lst]

    pool = mp.Pool(processes=4)
    res = pool.map(getImages, lst)

    print ("tempw")

它经常在列表中途卡住(它打印完成,或者无法下载到它已处理的列表的一半,但我不知道其余部分发生了什么)。有没有人遇到过这个问题?我已经搜索过类似的问题(例如这个link)但没有找到答案。

提前致谢

【问题讨论】:

    标签: python multiprocessing urllib python-multiprocessing


    【解决方案1】:

    好的,我找到了答案。

    一个可能的罪魁祸首是脚本卡在从 URL 连接/下载。所以我添加了一个socket timeout来限制连接和下载图像的时间。

    现在,这个问题不再困扰我了。

    这是我的完整代码

    ...
    import multiprocessing as mp
    
    import socket
    
    # Set the default timeout in seconds
    timeout = 20
    socket.setdefaulttimeout(timeout)
    
    def getImages(val):
    
        #Dowload images
        try:
            url= # preprocess the url from the input val
            local= #Filename Generation From Global Varables And Rand Stuffs...
            urllib.request.urlretrieve(url,local)
            print("DONE - " + url)
            return 1
        except Exception as e:
            print("CAN'T DOWNLOAD - " + url )
            return 0
    
    if __name__ == '__main__':
    
        files = "urls.txt"
        lst = list(open(files))
        lst = [l.replace("\n", "") for l in lst]
    
        pool = mp.Pool(processes=4)
        res = pool.map(getImages, lst)
    
        print ("tempw")
    

    希望这个解决方案可以帮助面临同样问题的其他人

    【讨论】:

      【解决方案2】:

      您似乎面临 GIL 问题:python 全局解释器锁基本上禁止 python 同时执行多个任务。 Multiprocessing 模块实际上是在启动单独的 python 实例以并行完成工作。

      但是在您的情况下,在所有这些实例中都会调用 urllib:它们中的每一个都试图锁定 IO 进程:成功的人(例如先来)会得到结果,而其他人(试图锁定已经锁定进程)失败。

      这是一个非常简单的解释,但这里有一些额外的资源:

      您可以在此处找到另一种并行化请求的方法:Multiprocessing useless with urllib2?

      这里有更多关于 GIL 的信息:What is a global interpreter lock (GIL)?

      【讨论】:

      • 感谢您的回复。我不确定 GIL 是不是罪魁祸首,但了解 GIL 是可能的情况之一很有用。
      猜你喜欢
      • 2016-03-09
      • 1970-01-01
      • 1970-01-01
      • 2015-01-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多