R doParallel foreach工作者超时错误并且永不返回

use*_*068 5 foreach timeout r worker doparallel

以下问题是与此处描述的问题相关的非常详细的问题。上一个问题

使用Ubuntu Server 14.04 LTS 64位Amazon Machine Image在具有R版本3.2.3的c4.8xlarge(36核)上启动。

考虑以下代码

library(doParallel)
cl=makeCluster(35)
registerDoParallel(cl)

tryCatch({
  evalWithTimeout({
    foreach(i=1:10) %:%
      foreach(j=1:50) %dopar% {
        tryCatch({
          evalWithTimeout({
            set.seed(j)
            source(paste("file",i,".R", sep = "")) # File that takes a long time to run
            save.image(file=paste("file", i, "-run",j,".RData",sep=""))
          },
          timeout=300); ### Timeout for individual processes
        }, TimeoutException=function(ex) {
          return(paste0("Timeout 1 Fail ", i, "-run", j))

        })
      }
  },
  timeout=3600); ### Cumulative Timeout for entire process
}, TimeoutException=function(ex) {

  return("Timeout 2 Fail")

})

stopCluster(cl)
Run Code Online (Sandbox Code Playgroud)

请注意,这两个超时异常均有效。我们注意到单个进程超时,如果有必要,还会出现累积进程超时。

但是,我们发现单个进程可以启动,并且由于未知的原因,300秒后不会超时。请注意,单个进程超时可确保该进程不会“花费很长时间”。结果,内核被该单个进程占据,并以100%的速度运行,直到达到3600秒的累积超时。请注意,如果累积超时不到位,则该过程及其核心将被无限期占用,并且foreach循环将无限期继续。一旦达到累积时间,将返回“超时2失败”,脚本将继续。

问题:如果某个单独的工作进程以某种方式“挂起”,即使单独的超时机制也无法正常工作,那么如何重新启动该工作程序,以便继续在并行处理中使用它?如果无法重新启动工作程序,是否可以以达到累积超时时以外的其他方式停止工作程序?这样做将确保在仅运行单个“错误”进程时,该进程不会在“等待”达到累积超时的延长时间内继续进行。

附加信息 该行为涉及“逃跑”过程或“吊死”工人。使用htop查看进程,其状态为运行100%CPU。以下链接是该进程的gdb backtrace调用的屏幕截图

回溯截图

问题:回溯中是否确定了“失控”过程的原因?

Bra*_*sen 1

我多次尝试让 evalWithTimeout 在非常相似的上下文中工作。我发现这是一个非常有问题的问题,特别是如果您使用数据库连接或全局变量。然而,对我来说非常有效的是创建一个使用setTimeLimit. 要正确使用它,您必须将它和您的函数包装在一起{}。这是一个例子:

foreach(...) %dopar% {
  withCallingHandlers({ 
    setTimeLimit(360)
    # your function goes here, runs for 360 seconds, or fails
    }, 
    error = function(e) {
    # do stuff to capture error messages here
    }
  )
}
Run Code Online (Sandbox Code Playgroud)

我使用 withCallingHandlers 是因为堆栈跟踪非常有用并且可以深入了解正在发生的事情。在我的错误函数中,我通常会适当地捕获详细的错误消息,以便我可以查看出现问题的内容和位置。

总结一下:

  1. setTimeLimit 一般来说比 evalWithTimeout 更可靠
  2. 使用 withCallingsHandlers 为您提供了出色的错误处理选项和比 tryCatch 更详细的输出
  3. 请记住将错误消息保存在有用的地方并对其进行格式化,以便您可以看到到底发生了什么。