多处理for循环?


81

我有一个数组(称为data_inputs),其中包含数百个天文学图像文件的名称。然后处理这些图像。我的代码有效,并且需要几秒钟来处理每个图像。但是,一次只能执行一张图像,因为我是通过for循环运行阵列:

for name in data_inputs:
    sci=fits.open(name+'.fits')
    #image is manipulated

没有理由我必须先修改映像,因此是否有可能利用计算机上的所有4个内核,每个内核都通过for循环在不同的映像上运行?

我已经阅读了有关该multiprocessing模块的信息,但是不确定如何在我的情况下实现它。我渴望开始multiprocessing工作,因为最终我将不得不在10,000幅以上的图像上运行它。

Answers:


99

您可以简单地使用multiprocessing.Pool:

from multiprocessing import Pool

def process_image(name):
    sci=fits.open('{}.fits'.format(name))
    <process>

if __name__ == '__main__':
    pool = Pool()                         # Create a multiprocessing Pool
    pool.map(process_image, data_inputs)  # process data_inputs iterable with pool

14
最好使用:pool = Pool(os.cpu_count()) 这是使用多重处理的更通用的方式。
— Lior Magen

2
注意:os.cpu_count()是在Python 3.4中添加的。对于Python 2.x,请使用multiprocessing.cpu_count()。
— dwj

22
Pool()与Pool(os.cpu_count())
— Tim

18
要详细说明@Tim的注释Pool()(不带for的注释)processes与Pool(processes=cpu_count())无论使用的是Python 3还是2都是相同的-因此,最好使用EITHER版本Pool()。docs.python.org/2/library/multiprocessing.html
— Monkpit '16

7
@LiorMagen,如果我没记错的话,使用Pool(os.cpu_count())会使操作系统冻结,直到处理结束,因为您不会离开操作系统任何空闲的内核。对于很多用户,Pool(os.cpu_count()-1)可能是一个更好的选择
— shayelk

23

您可以使用multiprocessing.Pool:

from multiprocessing import Pool
class Engine(object):
    def __init__(self, parameters):
        self.parameters = parameters
    def __call__(self, filename):
        sci = fits.open(filename + '.fits')
        manipulated = manipulate_image(sci, self.parameters)
        return manipulated

try:
    pool = Pool(8) # on 8 processors
    engine = Engine(my_parameters)
    data_outputs = pool.map(engine, data_inputs)
finally: # To make sure processes are closed in the end, even if errors happen
    pool.close()
    pool.join()

1
我无法理解什么是“ data_inputs”。您尚未定义。我应该给它什么价值?
— Abhishek dot py

1
它实际上源于alko的回答,我引用了他的评论(请参阅代码块):“使data_inputs可通过pool迭代”。因此data_inputs是可迭代的(就像在标准中一样map)。
— ponadto

该蟒蛇文档只能说明一个可以通过一个函数pool.map(func, iterable[, chunksize])。传递对象时,该对象将被所有进程共享吗?因此,可以让所有进程写入self.list_对象中的相同列表吗?
— 菲利普

6

或者

with Pool() as pool: 
    pool.map(fits.open, [name + '.fits' for name in datainput])

TypeError: 'Pool' object is not callable
— 克里斯,

抱歉,我的错误是“ pool.map”而不仅仅是“ pool”。我修好了它。
— 温泉
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.