我编写了以下两种方法,试图从多线程中受益:
class Data:
def read_single_image(self, resample_size, index, image_directory_path):
file_name = self.file_names[index]
file_path = os.path.join(image_directory_path, file_name + '.*')
files = glob.glob(file_path)
if len(files) != 1:
raise FileNotFoundError(errno.ENOENT, os.strerror(errno.ENOENT), file_path)
image = misc.imread(file_path, mode='RGB')
zoom = image.shape
# image = interpolation.zoom(image_directory_path)
zoom = (resample_size[0] / zoom[0], resample_size[1] / zoom[1], 1)
image = interpolation.zoom(image, zoom)
return image
def read_images(self, resample_size, indice=None, image_directory_path=train_jpeg_directory_path):
if indice is None:
indice = self.shuffled_indice
# reading all images into list
images = []
# for i in indice:
# image = self.read_single_image(resample_size, i, image_directory_path)
# images.append(image)
with ThreadPoolExecutor(cpu_count()) as pool:
for image in pool.map(self.read_single_image, [(resample_size, i, image_directory_path) for i in indice]):
images.append(image)
return np.stack(images)
不幸的是,它不适用于错误消息:
TypeError: read_single_image() missing 2 required positional arguments: 'index' and 'image_directory_path'
为什么?
答案 0 :(得分:1)
Executor.map()
(因此ThreadPoolExecutor.map()
)获取一个iterable,并通过封闭池将其发送给每个worker一个项目。这意味着您的Data.read_single_image()
方法被调用为:self.read_single_image((resample_size, i, image_directory_path))
即获取所有参数的tuple
作为第一个参数(在隐含的self
之后),因此它会抱怨它没有收到最后两个位置参数。
您只需将Data.read_single_image()
签名更改为:Data.read_single_image(self, args)
,然后从args
元组resample_size
读取为args[0]
,{{1 } index
和args[1]
为image_directory_path
。
如果要保留签名,可以将代理扩展器编写为:
args[2]
然后从def _read_single_image(self, args):
return self.read_single_image(*args)
调用_read_single_image()
方法(即ThreadPoolExecutor.map()
)
请注意,如果您要进行一些严肃的处理,那么使用pool.map(self._read_single_image, [(resample_size, i, image_directory_path) for i in indice])
模块会更好,multiprocessing
仍然受到可怕的GIL的限制