【问题标题】:Kill futures from future_apply() on Linux在 Linux 上从 future_apply() 杀死期货
【发布时间】:2020-04-26 08:52:33
【问题描述】:

我使用future_lapply() 在 Linux 机器上并行我的代码。如果我提前终止进程,则只有一名工作人员被释放,并行进程继续存在。我知道我可以输入tools::pskill(PID) 来结束每个单独的进程,但这很乏味,因为我在 26 个内核上运行。

如果有办法从 R 对 linux 进行系统调用以获取所有活动的 PID?

我这样设置future_lapply

# set number of workers
works <- 26
plan(multiprocess, workers = works)
future_lapply(datas, function(data) {
  # do some long processes
}

如果我终止进程并运行top,我仍然会看到:

因为我的并行会话仍在运行。

更新会话信息:
version.string R 版本 3.6.2 (2019-12-12)
未来 1.12.0
future.apply 1.2.0

【问题讨论】:

  • (future 的作者在这里) 首先,让我们确定更多关于您的设置的内容。具体来说,您正在运行哪个版本的 R、future 和 future.apply?此外,topCOMMAND 列列出了rsession,这表明您在 RStudio 控制台中运行它 - 对吗?因此,我怀疑您还在 RStudio 中重新启用了 forked 处理,例如你已经设置了 R 选项future.fork.enable=TRUE。那是对的吗?了解所有这些将有助于您进行下一步。
  • @HenrikB 我正在从 R studio 运行未来,虽然我不知道变量 future.fork.enable 我的印象是多个 rsessions 表示在 R studio 之外运行的多个 R 实例。有没有更好的实现方式?
  • 感谢添加会话信息详细信息。现在我看到您正在运行相当旧的 future 和 future.apply 版本,这使讨论和解释变得复杂。你不更新这些是有原因的吗? PS。当您更新到未来 (>= 1.14.0) 时,您看到当您在 RStudio 控制台中运行时future.fork.enable 将有效地变为FALSE,从而导致plan(multisession) 而不是@987654337 @ 工作人员。 (我实际上怀疑你正在运行一个旧版本的未来,因为这个 + top 输出的内容)。
  • 自未来 1.14.0 以来,multicore 期货在 RStudio 控制台中被禁用,因为 they are considered unstable there。未来的软件包会产生关于此的信息警告,并提供更多详细信息。因此,当您使用plan(multicore) 时,未来将强制它变为plan(sequential)除非您在再次允许plan(multicore) 时设置options(future.fork.enable = TRUE)。现在,我和 AFAIU,RStudio 的人,建议不要在 RStudio 中使用多核处理,所以你最好使用plan(multisession)
  • 上述“绕道”的原因是,我相信它可以帮助您理解多核和多会话(以及 RStudio 对多核的建议)之间的这一重要区别,然后再了解您的(限制)选项是什么时候它涉及终止期货。仅供参考,多核是 forked 并行处理,所以这也会影响parallel::mclapply()registerDoMC()registerDoParallel(cores=n) 的 foreach。

标签: r linux parallel-processing r-future


【解决方案1】:

我希望这会有所帮助。

require(future)
works <- 26
plan(multiprocess, workers = works)
future_lapply(datas, function(data) {
  # do some long processes
})

# get all PIDs of the r processess
v <- listenv::listenv()  # requires listenv package
for (ii in 1:works) {
   v[[ii]] %<-% {
         Sys.getpid()
     }
}

for (i in 1:works) {
  #For windows
  system(sprintf("taskkill /F /PID %s", v[[i]]))

  #For Linux
  system(sprintf("kill -9 %s", v[[i]]))
}

祝你有美好的一天。

【讨论】:

  • 是的,这可以解决问题。我确实必须用tools::pskill(v[[i]]) 替换system(sprintf("kill -9 %s", v[[i]]))。可能与运行 Ubuntu 16.04.6 的操作系统有关。
  • 注意:请不要使用KILL -9 (SIGKILL) 作为首选。从很好的杀戮开始(SIGTERM 或 SIGQUIT)
  • 作为更新,我注意到某些类型的期货会阻止 v &lt;- listenv::listenv() # requires listenv package for (ii in 1:works) { v[[ii]] %&lt;-% { Sys.getpid() } } 被调用,因为它本身就是一个期货。我查看了库“ps”,它有一个函数 ps(),它调用带有所有 PID 号的top 输出的小标题。
猜你喜欢
  • 1970-01-01
  • 2019-03-08
  • 1970-01-01
  • 1970-01-01
  • 2018-11-15
  • 1970-01-01
  • 2010-11-17
  • 1970-01-01
  • 2017-08-25
相关资源
最近更新 更多