以下最小例子......
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
如何避免它们?
我在包中使用Rmpi
和parallel
的{{1}},这就是我要问的原因。请注意,这已发布here但我还没有收到答案。如果这很重要,我将使用Ubuntu 12.10,Emacs 24和R 2.15.2
答案 0 :(得分:3)
我在使用Open MPI 1.4.3构建的Rmpi安装中看到了这个问题。我假设您使用Ubuntu时也使用Open MPI。加载Rmpi调用MPI_Init
会导致SIGCHLD
信号被捕获而不是被忽略。我相信结果是SIGCHLD
现在将在mclapply
退出时分叉的子进程发送,这会意外中断select
中的mclapply
系统调用。如果这不会导致任何实际错误,您可以通过调用mclapply
内的suppressWarnings
来阻止警告消息。
Open MPI用户的邮件列表中有一个discussion of this issue,表明该问题已在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
处理程序,但我不知道是否有必要。