request.urlretrieve 在多处理中 Python 卡住了
request.urlretrieve in multiprocessing Python gets stuck
我正在尝试使用 Python 从 URL 列表下载图像。为了加快处理速度,我使用了多处理库。
我面临的问题是脚本经常 hangs/freezes 自己,我不知道为什么。
这是我正在使用的代码
...
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")
它经常在列表中途卡住(它打印 DONE,或 CAN't DOWNLOAD 到它已处理的列表的一半,但我不知道其余部分发生了什么)。有没有人遇到过这个问题?我已经搜索过类似的问题(例如这个link)但没有找到答案。
提前致谢
您似乎遇到了 GIL 问题:python 全局解释器锁基本上禁止 python 同时执行多个任务。
Multiprocessing
模块实际上是在启动 python 的单独实例以并行完成工作。
但在你的情况下,urllib 在所有这些实例中被调用:它们中的每一个都试图锁定 IO 进程:成功的(例如先来的)给你结果,而其他的(试图锁定一个已经锁定的进程)失败。
这是一个非常简单的解释,但这里有一些额外的资源:
您可以在此处找到另一种并行化请求的方法:Multiprocessing useless with urllib2?
这里有关于 GIL 的更多信息:What is a global interpreter lock (GIL)?
好的,我找到答案了。
一个可能的罪魁祸首是脚本卡在了 URL 的 connecting/downloading 中。所以我添加的是 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")
希望这个解决方案能帮助其他面临同样问题的人
我正在尝试使用 Python 从 URL 列表下载图像。为了加快处理速度,我使用了多处理库。
我面临的问题是脚本经常 hangs/freezes 自己,我不知道为什么。
这是我正在使用的代码
...
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")
它经常在列表中途卡住(它打印 DONE,或 CAN't DOWNLOAD 到它已处理的列表的一半,但我不知道其余部分发生了什么)。有没有人遇到过这个问题?我已经搜索过类似的问题(例如这个link)但没有找到答案。
提前致谢
您似乎遇到了 GIL 问题:python 全局解释器锁基本上禁止 python 同时执行多个任务。
Multiprocessing
模块实际上是在启动 python 的单独实例以并行完成工作。
但在你的情况下,urllib 在所有这些实例中被调用:它们中的每一个都试图锁定 IO 进程:成功的(例如先来的)给你结果,而其他的(试图锁定一个已经锁定的进程)失败。
这是一个非常简单的解释,但这里有一些额外的资源:
您可以在此处找到另一种并行化请求的方法:Multiprocessing useless with urllib2?
这里有关于 GIL 的更多信息:What is a global interpreter lock (GIL)?
好的,我找到答案了。
一个可能的罪魁祸首是脚本卡在了 URL 的 connecting/downloading 中。所以我添加的是 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")
希望这个解决方案能帮助其他面临同样问题的人