Python多处理在绘图过程中悬挂



我正在使用Python的多处理模块挂起的代码,没有警告或错误。我认为我将其缩小到生成地块时。多处理和matplotlib之间是否存在一些不兼容?

我正在Python(使用Numpy,Scipy,Pandas)中进行大量数据集。每个数据集由单独的数据文件集合组成。我在原始数据中阅读,并为每个数据集编写一个.pkl文件和几个.png文件。使用Matplotlib和Seaborn生成地块。数字可以保存到不显示的情况下。每个数据集的预处理应完全彼此独立。

处理串行工作。preprocess.main_debug()输入路径/文件名/flags并返回状态字符串('complete',``跳过''等):

import preprocess
# Serial processing
dataroot = '/Volumes/ExtData/'
study = 'study0'
datasets = ['data0', 'data1', 'data2']
force_preprocess = True
quiet_console = False
status = [preprocess.main_debug(dataroot, study, dataset,
                                force_preprocess, quiet_console)
          for dataset in datasets]
# Print summary
print('n---- Summary --------------')
for d, s in zip(datasets, status):
    print(' {}:t{}'.format(d, s))

但多处理挂起:

import multiprocessing as mp
import logging
import preprocess
dataroot = '/Volumes/ExtData/'
study = 'study0'
datasets = ['data0', 'data1', 'data2']
force_preprocess = True
quiet_console = True  # Suppress console output
# Send multiprocessing logs to console
mp.log_to_stderr()
logger = mp.get_logger()
logger.setLevel(logging.INFO)
# Parallel process
pool = mp.Pool(processes=3, maxtasksperchild=1)
results = [pool.apply_async(preprocess.main_debug,
                            args=(dataroot, study, dataset,
                            force_preprocess, quiet_console)) 
           for dataset in datasets]
status = [p.get(timeout=None) for p in results]
# Print summary
print('n---- Summary --------------')
for d, s in zip(datasets, status):
  print(' {}:t{}'.format(d, s))

我已经摆弄了流程的数量,maxasksperchild和超时。我在网上找到了一些链接,表明日志记录和多处理之间可能存在一些不相容性,因此我删除了所有记录代码,但是执行方式以相同的方式挂起。

当我运行代码的多处理版本时,我在控制台中看到了这一点。

$ python batchpreprocess.py 
[INFO/PoolWorker-1] child process calling self.run()
[INFO/PoolWorker-2] child process calling self.run()
[INFO/PoolWorker-3] child process calling self.run()

7分钟左右后,CPU使用率从100%下降到0%,内存使用率从〜12GB下降到〜3MB。然后,我看到另外3个儿童过程开始了。事情一直处于这种状态(至少过夜)。对我来说似乎很奇怪,因为我只使用3个数据集进行测试,所以我希望总共只有3个孩子。

$ python batchpreprocess.py 
[INFO/PoolWorker-1] child process calling self.run()
[INFO/PoolWorker-2] child process calling self.run()
[INFO/PoolWorker-3] child process calling self.run()
[INFO/PoolWorker-4] child process calling self.run()
[INFO/PoolWorker-5] child process calling self.run()
[INFO/PoolWorker-6] child process calling self.run()  

我用日志记录语句洒了我的代码。它崩溃了,我的绘图代码将生成波形的绘图。如果我删除绘图代码,则执行将持续到该点,但随后将其悬挂在下一个地块上。

preprocess.main_debug()的内容如下:

def main_debug(dataroot, study, dataset, force_preprocess, quiet_console):  
    try:
        status = main(dataroot, study, dataset,
                      force_preprocess, quiet_console)
        return status
    except:
        print('Problem in dataset {}'.format(dataset))
        return 'Exception'
def main(dataroot, study, dataset, force_preprocess, quiet_console):
    ...
    [load files, do signal processing, make plots, save .pkl file]
    ...
    return 'Done'

我需要将图作为预处理的一部分制作。(可以从保存的PKL文件中绘制,但需要重新执行大多数代码。)我希望其他人跨过类似的东西并知道工作能力。

谢谢,

derek

Python 2.7,OSX High Sierra,刚刚使用Anaconda更新了我所有的包裹。

如果您拥有matplotlib集使用交互式后端,则该图将创建需要关闭主循环才能继续的窗口。

要避免这种情况,请使用非相互作用的后端,例如" agg"。

您可以在matplotlibrc文件中设置参数。

您也可以,先验导入pyplot,您可以做:

import matplotlib
matplotlib.use('agg')

最新更新