Python 多处理在绘图期间挂起

标签 python python-2.7 matplotlib multiprocessing freeze

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

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

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

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))

我摆弄过进程数、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')

关于Python 多处理在绘图期间挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47933420/

相关文章:

python - Pandas Dataframe - 生成增量值

python - 如何以 pandastic 方式绘制堆叠条形图?

android - 如何为 Kivy 中的按钮添加功能

python - 如何在 Python 中找到与谓词匹配的序列中的第一个元素?

python - python中matlab find函数的替换

python - 在不清除图形的情况下删除流图(matplotlib)

python - 如何使用 Matplotlib 制作简单的 3D 线?

python - 识别日期格式并将其更改为另一种格式

使用正则表达式进行 Python 文件搜索

python - 字典理解问题