2013-04-27 46 views
6

我正在尝试使用多处理来计算和生成图。在Linux下面的代码运行正常,但在Mac(ML)不是,给下面的错误:Python rpy2和matplotlib在使用多处理时发生冲突

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 

任何想法?

+1

Rpy2-2.3.6今天早些时候发布。它应该解决在OS X上的段错误。 – lgautier 2013-04-27 17:32:23

+0

Laurent,非常感谢你为新的rpy2版本。它现在可以与R 3.0.0一起使用。不过,上面的错误保持不变:/ – 2013-04-27 20:54:20

回答

6

当你在主线程之外执行一个GUI操作时,这个错误发生在Mac OS X上,这正是通过将你的绘图功能转移到multiprocessing.Pool(我想象它不能在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() 

希望这有助于。

1

这可能是rpy2特有的。 有报告说OS X和多处理器herethere有类似的问题。

我认为使用一个初始化工具可以解决问题(multiprocessing-doc),导入运行代码所需的软件包。

5

我和我的工作人员有类似的问题,他正在加载一些数据,生成一个图并将其保存到一个文件中。请注意,这与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 
+0

这正是我的问题,所以感谢张贴,即使它不是OP的问题:)。出于好奇 - 任何想法*为什么*改变后端修复事情?我的后端默认是'macosx',所以看起来这个问题并不是特定于'TkAgg'后端(当我评论出来,事情奏效的时候)。 – dwanderson 2016-10-26 15:44:34

相关问题