如何阻止R离开僵尸进程

时间:2014-08-17 11:02:31

标签: r foreach parallel-processing zombie-process

这是一个可重复的例子:

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

我启动R并查看流程表:

> system("ps -efl")
F S UID        PID  PPID  C PRI  NI ADDR SZ WCHAN  STIME TTY          TIME CMD
4 S chbr         1     0  5  80   0 - 21399 wait   10:58 ?        00:00:00 /usr/local/lib/R/bin/exec/R --no-save --no-restore
0 S chbr         9     1  0  80   0 -  1113 wait   10:58 ?        00:00:00 sh -c ps -efl
0 R chbr        10     9  0  80   0 -  4294 -      10:58 ?        00:00:00 ps -efl

如果我使用前面提到的简单for循环doMCdoParallel,则会留下僵尸进程。运行循环后输出ps -efl

> system("ps -efl")
F S UID        PID  PPID  C PRI  NI ADDR SZ WCHAN  STIME TTY          TIME CMD
4 S chbr         1     0  4  80   0 - 25256 wait   11:00 ?        00:00:00 /usr/local/lib/R/b
1 Z chbr        10     1  0  80   0 -     0 exit   11:00 ?        00:00:00 [R] <defunct>
0 S chbr        12     1  0  80   0 -  1113 wait   11:00 ?        00:00:00 sh -c ps -efl
0 R chbr        13    12  0  80   0 -  4294 -      11:00 ?        00:00:00 ps -efl

如果我重复循环而不再发出registerDoMC(4)则不会创建额外的僵尸进程。但是,如果我发出registerDoMC(4),则会创建一个额外的僵尸进程:

> system("ps -efl")
F S UID        PID  PPID  C PRI  NI ADDR SZ WCHAN  STIME TTY          TIME CMD
4 S chbr         1     0  0  80   0 - 25554 wait   11:00 ?        00:00:01 /usr/local/lib/R/b
1 Z chbr        21     1  0  80   0 -     0 exit   11:02 ?        00:00:00 [R] <defunct>
1 Z chbr        22     1  0  80   0 -     0 exit   11:02 ?        00:00:00 [R] <defunct>
0 S chbr        26     1  0  80   0 -  1113 wait   11:03 ?        00:00:00 sh -c ps -efl
0 R chbr        27    26  0  80   0 -  4294 -      11:03 ?        00:00:00 ps -efl

我认为它可能是doMC,它正在做一些不应该做的事情。如果doMC导致这种情况,有办法阻止doMC让僵尸进程落后吗? (stopCluster()不起作用,因为首先没有创建集群。)

> sessionInfo()
R Under development (unstable) (2014-08-16 r66404)
Platform: x86_64-unknown-linux-gnu (64-bit)

locale:
 [1] LC_CTYPE=en_IE.UTF-8       LC_NUMERIC=C              
 [3] LC_TIME=en_IE.UTF-8        LC_COLLATE=en_IE.UTF-8    
 [5] LC_MONETARY=en_IE.UTF-8    LC_MESSAGES=en_IE.UTF-8   
 [7] LC_PAPER=en_IE.UTF-8       LC_NAME=C                 
 [9] LC_ADDRESS=C               LC_TELEPHONE=C            
[11] LC_MEASUREMENT=en_IE.UTF-8 LC_IDENTIFICATION=C       

attached base packages:
[1] parallel  stats     graphics  grDevices utils     datasets  methods  
[8] base     

other attached packages:
[1] doParallel_1.0.8 doMC_1.3.3       iterators_1.0.7  foreach_1.4.2   

loaded via a namespace (and not attached):
[1] codetools_0.2-8 compiler_3.2.0

1 个答案:

答案 0 :(得分:4)

这与foreach或doMC无关;正如Steve Weston在回答其他StackOverflow查询时指出的那样,doMC基本上只是mclapply的包装器,你可以看到通过简单调用mclapply创建的僵尸进程:

library(parallel)
mclapply(rep(5,4), rnorm)

在我的系统上,这会留下两个僵尸进程:

[richcalaway@richcalaway-pc ~]$ ps -efl | grep defunct
1 Z 1660945517 28701 28624  0 77  0 -     0 exit   12:00 pts/1    00:00:00 [R] <defunct>
1 Z 1660945517 28702 28624  0 78  0 -     0 exit   12:00 pts/1    00:00:00 [R] <defunct>
0 S 1660945517 28704 28308  0 78  0 - 15306 pipe_w 12:00 pts/2    00:00:00 grep defunct

在正常情况下,这些僵尸进程不会造成任何麻烦,并且当R会话结束时它们确实会消失。您可以使用doParallel和fork集群而不是使用doMC来避免它们。

干杯,

Rich Calaway

首席项目经理

革命分析