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调用的屏幕截图
问题:回溯中是否确定了“失控”过程的原因?
我多次尝试让 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 是因为堆栈跟踪非常有用并且可以深入了解正在发生的事情。在我的错误函数中,我通常会适当地捕获详细的错误消息,以便我可以查看出现问题的内容和位置。
总结一下: