foreach 循环中 mclapply 出现 R 错误

标签 r parallel-processing parallel-foreach mclapply

基于this post here ,我尝试编写一个脚本,见这里:

library(parallel)
library(doParallel)

cl<-makeCluster(2,outfile='')
registerDoParallel(cl)

foreach(i=1:5, .packages='parallel') %dopar% {
    system.time(mclapply(1:10, function(x){rnorm(1e5)},mc.cores=2))
}

stopCluster(cl)

它最初有效,但现在抛出错误代码:

Error in unserialize(node$con) : error reading from connection
Calls: <Anonymous> ... doTryCatch -> recvData -> recvData.SOCKnode -> unserialize
Execution halted
Error in unserialize(socklist[[n]]) : error reading from connection
Error in unserialize(node$con) : error reading from connection
Calls: <Anonymous> ... doTryCatch -> recvData -> recvData.SOCKnode -> unserialize
Execution halted

知道发生了什么吗?甚至可以将 mclapply 放入 foreach 循环中吗?

编辑:我还想说这是在单个 8 核机器上,而不是集群上。

最佳答案

我能够仅使用 R 3.2.3 中的“并行”包在我的 Linux 计算机上重现您的问题:

library(parallel)
cl <- makeCluster(2)
clusterEvalQ(cl, library(parallel))
fun <- function(i) {
  mclapply(1:10, function(x) rnorm(1e5), mc.cores=2)
  0
}
clusterApplyLB(cl, 1:5, fun)

从我的调试 session 来看,主节点和工作节点之间的套接字连接可能会损坏,这可能会导致工作节点在尝试从损坏的套接字连接中“反序列化”数据时出现错误而死亡。

有趣的是,我可以通过使用“多核”包而不是“并行”来使这个示例正常工作。我使用以下命令从 RForge.net 安装了多核 0.1-8:

> install.packages('multicore',,'http://www.rforge.net/')  

然后,我在工作线程上加载了“多核”而不是“并行”:

clusterEvalQ(cl, library(multicore))

然后这个例子运行得很好。您可以更改 foreach 循环以使用 .packages='multicore' 选项。

据我所知,这就是它的情况。我的猜测是,“并行”中的“mclapply” fork 的子进程以某种方式破坏了它们继承的套接字连接,但我还没有查看代码来看看该理论是否合理。

我猜你的选择是:

  1. 不要在“doParallel”foreach 循环中使用“mclapply”
  2. 使用“多核 0.1-8”中的“mclapply”而不是“并行”
  3. 向 R-Core 报告此问题

您必须做额外的工作才能向 R-Core 报告此问题,但希望我的示例能有所帮助。

关于foreach 循环中 mclapply 出现 R 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35491015/

相关文章:

regex - gsub 返回\n(换行符)

c# - Task.WhenAll 结果排序

parallel-processing - goroutines 在多核处理器上的表现如何

r - foreach、doParallel 和随机生成

r - 如何并行化 R 中包的函数

r - R不知道时间是循环的吗?如何找到一天中最接近给定时间的时间

java - 安装 R 包时出错

r - 在 ggplot2 中标记 geom_rect()

powershell - 如何增加与 Powershell 3 并行的进程数?

r - 使用 foreach 时如何记录(打印或 futile.logger)