【问题标题】:R parallel computing and zombie processesR 并行计算和僵尸进程
【发布时间】:2014-10-12 19:58:37
【问题描述】:

这基本上是对this 更专业问题的跟进。 R有一些关于并行计算时创建僵尸进程的帖子:

  1. How to stop R from leaving zombie processes behind
  2. How to kill a doMC worker when it's done?
  3. Remove zombie processes using parallel package

有几种方法可以进行并行计算,我将重点介绍迄今为止我在本地计算机上使用过的三种方法。我在本地计算机上使用doMCdoParallelforeachpackage 和4cores:

(a) 注册一个分叉集群:

library(doParallel)
cl <- makeForkCluster(4)
# equivalently here: cl <- makeForkCluster(nnodes=getOption("mc.cores", 4L))
registerDoParallel(cl)
    out <- foreach(i=1:1000, .combine = "c") %dopar% {
        print(i)
    }
stopCluster(cl)

(b) 注册 PSOCK 集群:

library(doParallel)
cl <- makePSOCKcluster(4)
registerDoParallel(cl)
    out <- foreach(i=1:1000, .combine = "c") %dopar% {
        print(i)
    }
stopCluster(cl)

(c) 使用doMC

library(doMC)
library(doParallel)
registerDoMC(4)
    out <- foreach(i=1:1000, .combine = "c") %dopar% {
        print(i)
    }

一些用户观察到,当使用doMC 方法时——它只是mclapply 函数的包装,因此它不是doMCs 错误(参见此处:How to kill a doMC worker when it's done?)——留下僵尸进程.在对上一个问题 (How to stop R from leaving zombie processes behind) 的回答中,有人建议使用 fork 集群可能不会留下僵尸进程。在另一个问题中,有人建议 (Remove zombie processes using parallel package) 使用 PSOCK 集群可能不会留下僵尸进程。但是,似乎所有三种方法都将僵尸进程抛在脑后。虽然僵尸进程本身通常不是问题,因为它们(通常)不绑定资源,但它们会使进程树变得混乱。我仍然可以通过关闭并重新打开R 来摆脱它们,但是当我处于会话中间时,这不是最好的选择。是否有解释为什么会发生这种情况(甚至:有理由为什么会发生这种情况)?有没有什么办法可以避免僵尸进程被遗忘?

我的系统信息(R 用于与xtermtmux 的简单repl 会话):

library(devtools)
> session_info()
Session info-------------------------------------------------------------------
 setting  value                                             
 version  R Under development (unstable) (2014-08-16 r66404)
 system   x86_64, linux-gnu                                 
 ui       X11                                               
 language (EN)                                              
 collate  en_IE.UTF-8                                       
 tz       <NA>                                              

Packages-----------------------------------------------------------------------
 package    * version  source          
 codetools    0.2.8    CRAN (R 3.2.0)  
 devtools   * 1.5.0.99 Github (c429ae2)
 digest       0.6.4    CRAN (R 3.2.0)  
 doMC       * 1.3.3    CRAN (R 3.2.0)  
 evaluate     0.5.5    CRAN (R 3.2.0)  
 foreach    * 1.4.2    CRAN (R 3.2.0)  
 httr         0.4      CRAN (R 3.2.0)  
 iterators  * 1.0.7    CRAN (R 3.2.0)  
 memoise      0.2.1    CRAN (R 3.2.0)  
 RCurl        1.95.4.3 CRAN (R 3.2.0)  
 rstudioapi   0.1      CRAN (R 3.2.0)  
 stringr      0.6.2    CRAN (R 3.2.0)  
 whisker      0.3.2    CRAN (R 3.2.0)  

小编辑:至少对于makeForkCluster() 而言,似乎有时它产生的叉子会被父母正确地杀死和收割,有时它们不会被收割并变成僵尸。似乎只有在循环中止或完成后集群没有足够快地关闭时才会发生这种情况;至少那是最近几次发生的时候。

【问题讨论】:

    标签: r parallel-processing zombie-process


    【解决方案1】:

    您可以使用“内联”包摆脱僵尸进程。只需实现一个调用“waitpid”的函数:

    library(inline)
    includes <- '#include <sys/wait.h>'
    code <- 'int wstat; while (waitpid(-1, &wstat, WNOHANG) > 0) {};'
    wait <- cfunction(body=code, includes=includes, convention='.C')
    

    我首先使用 mclapply 函数创建了一些僵尸来对此进行测试:

    > library(parallel)
    > pids <- unlist(mclapply(1:4, function(i) Sys.getpid(), mc.cores=4))
    > system(paste0('ps --pid=', paste(pids, collapse=',')))
      PID TTY          TIME CMD
    17447 pts/4    00:00:00 R <defunct>
    17448 pts/4    00:00:00 R <defunct>
    17449 pts/4    00:00:00 R <defunct>
    17450 pts/4    00:00:00 R <defunct>
    

    (请注意,我使用的是支持“--pid”选项的 GNU 版本的“ps”。)

    然后我调用我的“等待”函数并再次调用“ps”以验证僵尸已经消失:

    > wait()
    list()
    > system(paste0('ps --pid=', paste(pids, collapse=',')))
      PID TTY          TIME CMD
    

    mclapply 创建的工作进程似乎已经消失了。只要进程是由当前 R 进程创建的,这应该可以工作。

    【讨论】:

    • 谢谢你的这个...救命稻草
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-12
    • 2012-03-18
    • 2011-11-09
    • 1970-01-01
    • 2014-09-30
    • 1970-01-01
    相关资源
    最近更新 更多