r语言 - Rmpi : mclapply: in selectChildren(ac, 1) : 在 select 中出现错误"中断的系统调用"



下面的最小示例…

require(Rmpi)
set.seed(1)
foo <- parallel::mclapply(seq_len(10), function(l)
                          lapply(1:10, function(x) mean(rnorm(10000, mean=x))),
                          mc.cores=4)

…生成类型为

的警告消息
1: In selectChildren(ac, 1) : error 'Interrupted system call' in select
2: In selectChildren(ac, 1) : error 'Interrupted system call' in select
3: In selectChildren(ac, 1) : error 'Interrupted system call' in select

如何避免?

我在一个包中使用Rmpiparallelmclapply,这就是我问的原因。请注意,这已经张贴在这里,但我还没有收到一个答案(尚未)。如果这很重要,我使用Ubuntu 12.10, Emacs 24和R 2.15.2

我在使用Open MPI 1.4.3构建的Rmpi安装中发现了这个问题。我猜你也在使用Open MPI,因为你使用的是Ubuntu。加载Rmpi调用MPI_Init,导致SIGCHLD信号被捕获而不是被忽略。我相信结果是SIGCHLD现在将在mclapply派生的子进程退出时发送,这意外地中断了mclapply中的select系统调用。如果这不会导致任何实际错误,您可以通过在suppressWarnings中调用mclapply来防止警告消息。

在Open MPI用户的邮件列表中有一个关于这个问题的讨论,表明这个问题在Open MPI 1.6系列的某个时候已经修复了,所以这个问题的最佳解决方案可能是升级你的MPI安装,如果你还没有升级的话。

我使用Open MPI 1.6.5和1.7.3尝试了您的示例,但问题仍然存在。我决定使用inline包来实现一个函数,该函数将SIGCHLD信号重置为默认处理。使用它,我可以运行您的示例而不生成任何警告:
library(Rmpi)
library(inline)
includes <- "#include <signal.h>"
code <- "signal(SIGCHLD, SIG_DFL);"
ignchld <- cfunction(body=code, includes=includes, convention=".C")
ignchld()
foo <- parallel::mclapply(seq_len(10), function(l)
                          lapply(1:10, function(x) mean(rnorm(10000, mean=x))),
                          mc.cores=4)

当然,禁用信号可能会给Rmpi带来一些问题。在这种情况下,您可以修改代码以保存和恢复SIGCHLD处理程序,但我不知道这是否必要。

最新更新