Python 多处理和rpy2(带ape)

Python 多处理和rpy2(带ape),python,r,multiprocessing,rpy2,ape-phylo,Python,R,Multiprocessing,Rpy2,Ape Phylo,我今天碰到这个,不知道为什么。我有几个链接在一起的函数,它们作为更大管道的一部分执行一些耗时的操作。我在这里尽我所能地将它们包括在内,简化为一个测试示例。问题是,当我直接调用一个函数时,我得到了预期的输出(例如,5个不同的树)。但是,当我使用apply_async(或apply,无所谓)在多处理池中调用相同的函数时,我得到了5棵树,但它们都是相同的 我在IPython笔记本中记录了这一点,可在此处查看: 在单元格91中,我创建了5棵树(每个树有10个提示),并返回两个列表。第一个包含非多处理树,

我今天碰到这个,不知道为什么。我有几个链接在一起的函数,它们作为更大管道的一部分执行一些耗时的操作。我在这里尽我所能地将它们包括在内,简化为一个测试示例。问题是,当我直接调用一个函数时,我得到了预期的输出(例如,5个不同的树)。但是,当我使用apply_async(或apply,无所谓)在多处理池中调用相同的函数时,我得到了5棵树,但它们都是相同的

我在IPython笔记本中记录了这一点,可在此处查看:

在单元格91中,我创建了5棵树(每个树有10个提示),并返回两个列表。第一个包含非多处理树,第二个来自apply_async

在单元格92中,您可以看到在不进行多重处理的情况下创建树的结果,在单元格93中,您可以看到在进行多重处理的情况下创建树的结果

我期望在两个测试之间总共有10个不同的树,但是所有的多处理树都是相同的。对我来说没什么意义

事物的相关版本:

  • Linux 2.6.18-238.12.1.el5 x86_64 GNU/Linux
  • Python 2.7.6::Anaconda 1.9.2(64位)
  • IPython 2.0.0
  • Rpy2.3.9
谢谢!
Chris

我对这些库不是100%熟悉,但是,在Linux上,(IIRC)
multi-processing
使用
os.fork
。这意味着随机模块(您正在使用)的状态也将被分叉,并且您的每个进程将生成相同的随机数序列,从而生成一个不太随机的
\u get\u random\u string
函数

如果我是对的,并且你使池小于你想要的树的数量,你应该看到你得到了N个相同的树的组(其中N是池的数量)


我认为理想的解决方案可能是在每个过程中使用随机数生成器。它们不太可能在同一时间运行,因此您应该会得到不同的结果。

我解决了这个问题,从@mgilson处找到了一个正确的方向。事实上,这是一个随机数问题,只是在python中不是这样——在R中(叹气)。创建池时复制R的状态,这意味着它的随机种子也是如此。为了解决这个问题,只需调用R的set.seed函数(使用一些特定于流程的内容进行适当的度量),如下所示的一点rpy2:


这是一个很好的电话,我会查一查。此外,我还将其设置为使用IPython.parallel()。没有多处理这样的问题,所以我想这是另一种选择。只是更多的设置。我甚至尝试了scipy.random.choice和scipy.random.seed,同样的问题。嗯,我越来越接近了,但是我仍然没有从我的代码中得到正确的东西,尽管测试是有效的。测试:,更新代码的新笔记本:
def create_tree(num_tips, type):
    """
    creates the taxa tree in R
    @param num_tips: number of taxa to create
    @param type: type for naming (e.g., 'taxa')
    @return: a dendropy Tree
    @rtype: dendropy.Tree
    """
    r = rpy2.robjects.r
    set_seed = r('set.seed')
    set_seed(int((time.time()+os.getpid()*1000)))
    rpy2.robjects.globalenv['numtips'] = num_tips
    rpy2.robjects.globalenv['treetype'] = type
    name = _get_random_string(20)
    if type == "T":
        r("%s = rtree(numtips, rooted=T, tip.label=paste(treetype, seq(1:(numtips)), sep=''))" % name)
    else:
        r("%s = rtree(numtips, rooted=F, tip.label=paste(treetype, seq(1:(numtips)), sep=''))" % name)
    tree = r[name]
    return ape_to_dendropy(tree)