我使用Python的多处理模块运行的代码挂起时没有任何警告或错误。我想我已经把它缩小到生成情节的时候。多处理和matplotlib之间是否存在一些不兼容性?
我正在使用Python(使用numpy,scipy,pandas)预处理大量数据集。每个数据集由一组独立的数据文件组成。我读入原始数据并为每个数据集编写一个.pkl文件和一些.png文件。使用matplotlib和seaborn生成图。数字保存到文件而不显示。每个数据集的预处理应完全相互独立。
处理连续工作。 preprocess.main_debug()接受path / filename / flags并返回状态字符串('complete','skipped'等):
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更新了我的所有软件包。
答案 0 :(得分:2)
如果你有matplotlib set使用交互式后端,那么这些图将创建需要关闭主循环才能继续的窗口。
要避免这种情况,请使用非交互式后端,例如“agg”。
您可以在matplotlibrc
文件中设置参数。
你也可以之前导入pyplot
,你可以这样做:
import matplotlib
matplotlib.use('agg')