如何通过在主模块和模块之间拆分代码的方式来实现多处理python代码?

时间:2019-04-09 08:47:13

标签: python multiprocessing

我需要计算长时间序列中每个图像的图像各部分的平均值。我正在处理约300个120MP图像,因此产生的计算量非常大。由于我正在使用python,因此我想克服单线程问题并利用我的多核处理器。我正在编写的项目也非常庞大,因此我将代码分为多个模块和一个“ main.py”脚本来管理所有内容。

我已经尝试遵循官方文档,一些在线教程和论坛问题,但是我目前遇到以下问题:

-多处理代码可以很好地启动(100%CPU使用率)并为每个内核计算大约50个周期,但是一段时间之后,它就暂停了。然后,再经过一些时间(例如10分钟)后,它将重新开始。这一直在重复。

-在Windows上运行时,在Linux上会生成RuntimeError(Already Started),并且不起作用。

-由于任务很长,所以我想看看我的代码的总体进度是什么:我目前正在让每个进程打印自己的状态进度,但这很麻烦。

在此示例中,我仅在图像上测试脚本。这是“ main.py”脚本:

from multiprocessing import freeze_support
if __name__ == '__main__':
    freeze_support()
    import module
    import numpy as np   

    img = np.load('ndvi.npy')
    label = np.load('label.npy')
    print('I AM IN MAIN')    

    module.get_cropTS_with_mp([img],label)

这是包含处理功能的“ module.py”脚本:

import numpy as np
from multiprocessing import Pool
from functools import partial


def get_cropTS_with_mp(ts, label):
    totImg = len(ts)
    totCrops = np.amax(label)

    cropTS = np.zeros( (totCrops, totImg), dtype=np.float32 )
    areaConst = np.zeros( (totCrops), dtype=np.float32)

    p = Pool()
    result = p.map( partial(_mp_cropArea, label=label), range(totCrops))
    p.close()
    p.join()

    p = Pool()
    result = p.map(  partial(_mp_avgIndex, label=label, totCrops=totCrops, ts=ts), range(totImg) )
    p.close()
    p.join()

    return None


def _mp_avgIndex(imgNum, ts, label, totCrops):
    print(imgNum)
    img = ts[imgNum].ndvi()
    avgCrops = np.zeros( (totCrops), dtype=np.float32 )

    for idx in range(totCrops):
        cropNum = idx+1        
        avgCrops[idx] = np.sum(img[label==cropNum])
    return avgCrops

def _mp_cropArea(idx , label):
    cropNum = idx + 1
    print('\n',cropNum)
    return np.sum(label==cropNum)

一些最终的“有用”信息:我使用python 3.6.7,Visual Studio Code作为IDE,并全部在具有16GB RAM和SSD的6核计算机上运行;当Scipt实际工作时,RAM使用量确实会飙升至15.5GB。

编辑:阻塞问题可能是由于尝试同时打印的单独进程引起的。在IDE中的“调试”和“终端”选项卡之间切换似乎会取消冻结代码。

0 个答案:

没有答案