r - mclapply 随机返回 NULL

标签 r parallel-processing mclapply

当我使用 mclapply 时,有时(非常随机)它会给出不正确的结果。该问题在 Internet 上的其他帖子中得到了非常详尽的描述,例如( http://r.789695.n4.nabble.com/Bug-in-mclapply-td4652743.html )。但是,没有提供解决方案。有谁知道如何解决这个问题?谢谢!

最佳答案

您引用的 Winston Chang 报告的问题似乎已在 R 2.15.3 中修复。 mccollect 中存在错误将工作人员结果分配给结果列表时发生的情况:

if (is.raw(r)) res[[which(pid == pids)]] <- unserialize(r)

如果 unserialize(r),这将失败返回 NULL,因为以这种方式将 NULL 分配给列表会删除列表的相应元素。这在 R 2.15.3 中更改为:
if (is.raw(r)) # unserialize(r) might be null
    res[which(pid == pids)] <- list(unserialize(r))

这是将未知值分配给列表的安全方法。

因此,如果您使用的是 R <= 2.15.2,则解决方案是升级到 R >= 2.15.3。如果您在使用 R >= 2.15.3 时遇到问题,那么大概是与 Winston Chang 报告的问题不同的问题。

我还阅读了由 Elizabeth Purdom 发起的 R-help 线程中讨论的问题。如果没有特定的测试用例,我的猜测是问题不是由 mclapply 中的错误引起的,因为我可以使用以下函数重现相同的症状:
work <- function(i, poison) {
  if (i == poison) quit(save='no')
  i
}

如果由 mclapply 启动的 worker 在执行任务时因任何原因(接收信号、段错误、退出)而死亡,mclapply 将为分配给该 worker 的所有任务返回 NULL:
> library(parallel)
> mclapply(1:4, work, 3, mc.cores=2)
[[1]]
NULL

[[2]]
[1] 2

[[3]]
NULL

[[4]]
[1] 4

在这种情况下,由于预调度,任务 1 和 3 返回了 NULL,即使实际上只有任务 3 失败了。

如果worker在使用parLapply或clusterApply等函数时死亡,会报错:
> cl <- makePSOCKcluster(3)
> parLapply(cl, 1:4, work, 3)
Error in unserialize(node$con) : error reading from connection

我见过很多这样的报告,我认为它们往往发生在使用大量包的大型程序中,这些包很难变成可重现的测试用例。

当然,在这个例子中,你在使用 lapply 时也会得到一个错误,虽然这个错误不会像 mclapply 那样被隐藏。如果问题在使用 lapply 时似乎没有发生,可能是因为问题很少发生,所以它只发生在使用 mclapply 并行执行的非常大的运行中。但也有可能出现错误,不是因为任务是并行执行的,而是因为它们是由 fork 的进程执行的。例如,各种图形操作在 fork 进程中执行时会失败。

关于r - mclapply 随机返回 NULL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20674538/

相关文章:

r - 有没有一种简洁的方法来读取 JSON 字符串并将其转换为新变量?

java - 如何在 Java 中以最高效和优雅的方式使用并行处理

java - JDBC查询多个数据库

r - 在 Linux 中使用 mclapply 时 R 中出现奇怪的段错误

r - 条形图 - 两个相邻的条形图和单独窗口中的条形图

r - 在 ggplot 中向轴标签添加额外文本

r - 为什么 R、Excel 和 VBA 中 Male > Female 等于 TRUE?其他语言怎么样?

vb.net - 并行循环和 Nlog

r - 有没有办法跟踪 mclapply 的进度?

将 apply 函数替换为 lapp