枚举循环中的多处理
Multiprocessing in enumerate loop
我有一个从 url 下载图像的脚本,但我想将它并行化,否则会花费数小时。使用此代码:
import requests
from math import floor, log10
import urllib
import time
import multiprocessing
with open('images.csv', 'r') as f:
images = f.readlines()
num_position = floor(log10(len(images)) + 1)
a = time.time()
for i, image in enumerate(images[1:10]):
if (i+1) % 1000 == 0:
print('Downloading {} image'.format(i+1) )
# a = time.time()
with open(str(i).zfill(num_position)+'a.jpg', 'wb') as file:
try:
writing = file.write(requests.get(image.split(',')[2]).content)
p = multiprocessing.Process(target=writing, args=(image,))
p.start()
p.join()
except:
print('Skipping an image!')
pass
b = time.time()
print('multiple process -- {}'.format(b-a))
我收到一个错误:
Process Process-9:
Traceback (most recent call last):
File "/usr/lib/python3.4/multiprocessing/process.py", line 254, in _bootstrap
self.run()
File "/usr/lib/python3.4/multiprocessing/process.py", line 93, in run
self._target(*self._args, **self._kwargs)
TypeError: 'int' object is not callable
- 为什么我收到错误但任务仍然完成并且代码没有中断? (我指的是尝试中的作品:)
- 在这里包含某种并行的最简单方法是什么?
你得到这个错误是因为 AFAIK 这一行
writing = file.write(requests.get(image.split(',')[2]).content)
有整数类型的输出。 write
returns 写入的字符数等于图像字符串表示的长度。现在你把它分配给变量 writing
-> writing
变成一个数字。
p = multiprocessing.Process(target=writing, args=(image,))
调用 writing
作为目标函数,这会引发错误,因为您调用的不是函数而是整数类型 writing
(不可调用)。该代码有效,因为您的工作人员没有任何事情要做并立即关闭并且文件已经写入。
为了让事情正常进行,您必须定义一个函数,将您的图像作为参数,也许还有文件名。您稍后会在您的工作人员的设置中调用此功能。类似的东西:
def write_file(image, filename):
filestream = open(filename, mode="w")
filestream.write(requests.get(image.split(',')[2]).content)
filestream.close()
并且在您的申请中
p = multiprocessing.Process(target=write_file, args=(image, filename,))
然而,这只是写作部分。如果您也想在单独的任务中进行下载,那么您必须将相关代码放入单独的函数中。
def download_write(urls):
for url in iter(urls.get, 'STOP'):
#download code here#
filestream = open(filename, mode="w")
filestream.write(requests.get(image.split(',')[2]).content)
filestream.close()
您的主要应用程序:
list_urls = [] # your list of urls to download
urls = Queue()
for element in list_urls:
urls.put(element)
p = multiprocessing.Process(target=download_write, args=(urls,))
urls.put("STOP") #signals end of tasks for your workers
p.start() #start worker
p.join() #wait for worker to finish
我有一个从 url 下载图像的脚本,但我想将它并行化,否则会花费数小时。使用此代码:
import requests
from math import floor, log10
import urllib
import time
import multiprocessing
with open('images.csv', 'r') as f:
images = f.readlines()
num_position = floor(log10(len(images)) + 1)
a = time.time()
for i, image in enumerate(images[1:10]):
if (i+1) % 1000 == 0:
print('Downloading {} image'.format(i+1) )
# a = time.time()
with open(str(i).zfill(num_position)+'a.jpg', 'wb') as file:
try:
writing = file.write(requests.get(image.split(',')[2]).content)
p = multiprocessing.Process(target=writing, args=(image,))
p.start()
p.join()
except:
print('Skipping an image!')
pass
b = time.time()
print('multiple process -- {}'.format(b-a))
我收到一个错误:
Process Process-9:
Traceback (most recent call last):
File "/usr/lib/python3.4/multiprocessing/process.py", line 254, in _bootstrap
self.run()
File "/usr/lib/python3.4/multiprocessing/process.py", line 93, in run
self._target(*self._args, **self._kwargs)
TypeError: 'int' object is not callable
- 为什么我收到错误但任务仍然完成并且代码没有中断? (我指的是尝试中的作品:)
- 在这里包含某种并行的最简单方法是什么?
你得到这个错误是因为 AFAIK 这一行
writing = file.write(requests.get(image.split(',')[2]).content)
有整数类型的输出。 write
returns 写入的字符数等于图像字符串表示的长度。现在你把它分配给变量 writing
-> writing
变成一个数字。
p = multiprocessing.Process(target=writing, args=(image,))
调用 writing
作为目标函数,这会引发错误,因为您调用的不是函数而是整数类型 writing
(不可调用)。该代码有效,因为您的工作人员没有任何事情要做并立即关闭并且文件已经写入。
为了让事情正常进行,您必须定义一个函数,将您的图像作为参数,也许还有文件名。您稍后会在您的工作人员的设置中调用此功能。类似的东西:
def write_file(image, filename):
filestream = open(filename, mode="w")
filestream.write(requests.get(image.split(',')[2]).content)
filestream.close()
并且在您的申请中
p = multiprocessing.Process(target=write_file, args=(image, filename,))
然而,这只是写作部分。如果您也想在单独的任务中进行下载,那么您必须将相关代码放入单独的函数中。
def download_write(urls):
for url in iter(urls.get, 'STOP'):
#download code here#
filestream = open(filename, mode="w")
filestream.write(requests.get(image.split(',')[2]).content)
filestream.close()
您的主要应用程序:
list_urls = [] # your list of urls to download
urls = Queue()
for element in list_urls:
urls.put(element)
p = multiprocessing.Process(target=download_write, args=(urls,))
urls.put("STOP") #signals end of tasks for your workers
p.start() #start worker
p.join() #wait for worker to finish