绘制期间Python多处理挂起

绘制期间Python多处理挂起,python,python-2.7,matplotlib,multiprocessing,freeze,Python,Python 2.7,Matplotlib,Multiprocessing,Freeze,我使用Python的多处理模块运行的代码挂起,没有任何警告或错误。我想我已经把范围缩小到了绘图的时间。多处理和matplotlib之间是否存在一些不兼容 我正在用Python(使用numpy、scipy和pandas)预处理大量数据集。每个数据集由一组单独的数据文件组成。我读入原始数据,为每个数据集编写一个.pkl文件和几个.png文件。使用matplotlib和seaborn生成绘图。图形将保存到文件而不显示。每个数据集的预处理应该彼此完全独立 处理连续工作。preprocess.main_d

我使用Python的多处理模块运行的代码挂起,没有任何警告或错误。我想我已经把范围缩小到了绘图的时间。多处理和matplotlib之间是否存在一些不兼容

我正在用Python(使用numpy、scipy和pandas)预处理大量数据集。每个数据集由一组单独的数据文件组成。我读入原始数据,为每个数据集编写一个.pkl文件和几个.png文件。使用matplotlib和seaborn生成绘图。图形将保存到文件而不显示。每个数据集的预处理应该彼此完全独立

处理连续工作。preprocess.main_debug()接受路径/文件名/标志并返回状态字符串(“完成”、“跳过”等):

但多处理挂起:

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))
我对进程数、maxtasksperchild和超时进行了调整,但没有任何效果。我在网上发现了一些链接,表明日志记录和多处理之间可能存在一些不兼容,因此我删除了所有日志记录代码,但执行以相同的方式挂起

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

$ 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文件打印是可能的,但需要重新执行大部分代码。)我希望其他人也遇到过类似的情况,并知道解决方法

谢谢

德里克


Python 2.7 OSX High Sierra刚刚使用anaconda更新了我的所有软件包。

如果matplotlib设置为使用交互式后端,绘图将创建需要关闭的窗口,以便主循环继续

要避免这种情况,请使用非交互式后端,如“agg”

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

在导入
pyplot
之前,您还可以执行以下操作:

import matplotlib
matplotlib.use('agg')

我对matplotlib有过一些问题,因为我从未完成我试图绘制的图形。事实证明,数据点太多了,而且一直挂在那里。你应该试着截断你的数据集,只绘制其中的一小部分,看看是否发生了这种情况。我没有看到任何绘图代码。那你确定那就是它挂的地方吗?您使用的是什么后端?如果不是AGG,试试AGG。看起来你不知怎么陷入了僵局。只有在进程共享资源的情况下才会发生这种情况,通常在多线程中发生这种情况的可能性比在多线程中要小。从我在你的帖子中看到的情况来看,多重处理的设置似乎都是正确的。能否添加
预处理.main\u调试的代码?或者至少是函数中的参数和变量的初始设置?感谢所有建议。结果证明@PaulH的建议是正确的。我使用的是MacOSX后端。我切换到Agg,脚本运行完成。太棒了!:)顺便说一句,我刚开始在论坛上发帖。。。结束这一切的最好办法是什么?谢谢,保罗。我从未在脚本中调用show(),所以我不希望出现任何窗口。但我确实在文档中看到了macosx的反常之处。“OSX窗口中的Cocoa渲染(当matplotlib处于非交互模式时,当前缺少阻塞显示()行为)”。也许这是有关系的。再次感谢你的帮助。
import matplotlib
matplotlib.use('agg')