一段代码挂起超过x秒如何重新运行?

How to re-run a piece of code if it hangs for more than x seconds?

我有一段代码,其执行时间各不相同。有时需要 5 秒,有时可能需要更长的时间。我想设置一个时间限制,使得 if 执行时间挂起超过 5 秒,then 中断并重新 运行代码(希望它会 运行 更快(即 <= 5 秒)。

我发现 R.utils::withTimeout() 很适合这个任务。但是,我不确定如何创建 re运行ning 循环。例如,考虑以下代码。 square_slowly() 是一个计算平方数的函数,具有不同的执行时间。 运行.

可能需要 1 到 10 秒之间的任何时间
square_slowly <- function(x) {
  idle_time <- sample(1:10, 1)
  Sys.sleep(idle_time)
  
  message(paste0("it took ", idle_time, " seconds"))
  return(x * x)
}

set.seed(100)

square_slowly(3)
#> it took 10 seconds
#> [1] 9

所以我要监控square_slowly():如果超过5秒,就重新运行。重复重新 运行 直到 5 秒或更快 运行 秒。

我想我需要一个 repeat() 循环,但不确定如何去做。


编辑


理想情况下,我想添加一条消息,以防发生这种情况 运行。也就是说,对于每一个re-运行,打印一条消息,例如more than 5 seconds have elapsed; re-running.

一种可能的实现方式:

run <- function(x,timeout) {
res <- tryCatch(R.utils::withTimeout(square_slowly(x),timeout=timeout),error=function(cond) NULL)
if (is.null(res)) res <- Recall(x,timeout)
return(res)
}

run(3,timeout = 5)
it took 4 seconds
[1] 9

或函数形式:

run <- function(.f,...,timeout,trial=1) {
  cat('run',trial,'\n')
  res <- tryCatch(R.utils::withTimeout(do.call(.f,list(...)),timeout=timeout),error=function(cond) NULL)
  if (is.null(res)) res <- Recall(.f=.f,unlist(list(...)),timeout=timeout,trial = trial + 1)
  return(res)
}
run(square_slowly,3,timeout = 5)

run 1 
run 2 
run 3 
run 4 
run 5 
run 6 
it took 4 seconds
[1] 9