我正在尝试使用多处理来计算和生成绘图。在Linux上,下面的代码运行正常,但在Mac(ML)上它没有运行,给出以下错误:
import multiprocessing
import matplotlib.pyplot as plt
import numpy as np
import rpy2.robjects as robjects
def main():
pool = multiprocessing.Pool()
num_figs = 2
# generate some random numbers
input = zip(np.random.randint(10,1000,num_figs),
range(num_figs))
pool.map(plot, input)
def plot(args):
num, i = args
fig = plt.figure()
data = np.random.randn(num).cumsum()
plt.plot(data)
main()
Rpy2是rpy2 == 2.3.1,R是2.13.2(我无法在任何mac上安装R 3.0和rpy2最新版本而不会出现分段错误)。
错误是:
The process has forked and you cannot use this CoreFoundation functionality safely. You MUST exec().
Break on __THE_PROCESS_HAS_FORKED_AND_YOU_CANNOT_USE_THIS_COREFOUNDATION_FUNCTIONALITY___YOU_MUST_EXEC__() to debug.
The process has forked and you cannot use this CoreFoundation functionality safely. You MUST exec().
我已经尝试了一切,以了解问题是什么,没有运气。我的配置是:
Danials-MacBook-Pro:~ danialt$ brew --config
HOMEBREW_VERSION: 0.9.4
ORIGIN: https://github.com/mxcl/homebrew
HEAD: 705b5e133d8334cae66710fac1c14ed8f8713d6b
HOMEBREW_PREFIX: /usr/local
HOMEBREW_CELLAR: /usr/local/Cellar
CPU: dual-core 64-bit penryn
OS X: 10.8.3-x86_64
Xcode: 4.6.2
CLT: 4.6.0.0.1.1365549073
GCC-4.2: build 5666
LLVM-GCC: build 2336
Clang: 4.2 build 425
X11: 2.7.4 => /opt/X11
System Ruby: 1.8.7-358
Perl: /usr/bin/perl
Python: /usr/local/bin/python => /usr/local/Cellar/python/2.7.4/Frameworks/Python.framework/Versions/2.7/bin/python2.7
Ruby: /usr/bin/ruby => /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby
有任何想法吗?
当您在主线程外部执行GUI操作时,在Mac OS X上会出现此错误,这正是您通过将绘图功能转移到multiprocessing.Pool所做的事情(我想它在Windows上也不会因为同样的原因而在Windows上运行) - 因为Windows有相同的要求)。我可以想象它工作的唯一方法是使用池来生成数据,然后让主线程在循环中等待返回的数据(队列是我通常处理它的方式......)。
这是一个例子(认识到这可能不会做你想要的 - 同时绘制所有数字? - plt.show()块,所以一次只绘制一个,我注意到你的样本中没有它代码 - 但没有我在屏幕上看不到任何内容 - 但是,如果我把它拿出来 - 没有阻塞也没有错误,因为所有的GUI功能都发生在主线程中):
import multiprocessing
import matplotlib.pyplot as plt
import numpy as np
import rpy2.robjects as robjects
data_queue = multiprocessing.Queue()
def main():
pool = multiprocessing.Pool()
num_figs = 10
# generate some random numbers
input = zip(np.random.randint(10,10000,num_figs), range(num_figs))
pool.map(worker, input)
figs_complete = 0
while figs_complete < num_figs:
data = data_queue.get()
plt.figure()
plt.plot(data)
plt.show()
figs_complete += 1
def worker(args):
num, i = args
data = np.random.randn(num).cumsum()
data_queue.put(data)
print('done ',i)
main()
希望这可以帮助。
我和我的工作人员有类似的问题,即加载一些数据,生成绘图并将其保存到文件中。请注意,这与OP的情况略有不同,后者似乎是围绕交互式绘图。不过,我认为这是相关的。
我的代码的简化版本:
def worker(id):
data = load_data(id)
plot_data_to_file(data) # Generates a plot and saves it to a file.
def plot_something_parallel(ids):
pool = multiprocessing.Pool()
pool.map(worker, ids)
plot_something_parallel(ids=[1,2,3])
这引起了其他人提到的同样错误:
The process has forked and you cannot use this CoreFoundation functionality safely. You MUST exec().
Break on __THE_PROCESS_HAS_FORKED_AND_YOU_CANNOT_USE_THIS_COREFOUNDATION_FUNCTIONALITY___YOU_MUST_EXEC__() to debug.
按照@bbbruce的思路,我通过将matplotlib后端从TKAgg
切换到默认值来解决我的问题。具体来说,我在matplotlibrc
文件中注释掉了以下行:
#backend : TkAgg
这可能是rpy2特定的。有报道称OS X和多处理here和there存在类似的问题。
我认为使用初始化程序导入运行代码中所需的包可以解决问题(multiprocessing-doc)。
尝试将matplotlib升级到3.0.3:
pip3 install matplotlib --upgrade
一切都很顺利。
=======================================================================
昨天,我的多进程图在我的MacBook Air上运行。但是明天早上没有使用相同的代码在我的MacBook Pro上工作,显示许多:
The process has forked and you cannot use this CoreFoundation functionality safely. You MUST exec().
Break on __THE_PROCESS_HAS_FORKED_AND_YOU_CANNOT_USE_THIS_COREFOUNDATION_FUNCTIONALITY___YOU_MUST_EXEC__() to debug.
The process has forked and you cannot use this CoreFoundation functionality safely. You MUST exec().
他们都使用第四代i intel CPU(i5-4xxx与air和i7-4xxx与pro)。因此,如果硬件没有区别,那么必须在软件上。
所以我只是尝试在MacBook Pro(3.0.1)上将matplotlib更新到3.0.3,一切都很顺利。
此外,不再需要做pool.apply_async
了。