我使用 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/