多处理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的注释)processesPool(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.