在Linux中递归地杀死带有子进程的R进程 [英] Recursively kill R process with children in linux

查看:431
本文介绍了在Linux中递归地杀死带有子进程的R进程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找一种启动并杀死R进程的通用方法,其中可能包括它调用的所有fork或其他进程.

I am looking for a general method to launch and then kill an R process, including possibly all forks or other processes that it invoked.

例如,用户运行这样的脚本:

For example, a user runs a script like this:

library(multicore);
for(i in 1:3) parallel(foo <- "bar");
for(i in 1:3) system("sleep 300", wait=FALSE);
for(i in 1:3) system("sleep 300&");
q("no")

用户退出R会话后,子进程仍在运行:

After the user quits the R session, the child processes are still running:

jeroen@jeroen-ubuntu:~$ ps -ef | grep R
jeroen    4469     1  0 16:38 pts/1    00:00:00 /usr/lib/R/bin/exec/R
jeroen    4470     1  0 16:38 pts/1    00:00:00 /usr/lib/R/bin/exec/R
jeroen    4471     1  0 16:38 pts/1    00:00:00 /usr/lib/R/bin/exec/R
jeroen    4502  4195  0 16:39 pts/1    00:00:00 grep --color=auto R
jeroen@jeroen-ubuntu:~$ ps -ef | grep "sleep"
jeroen    4473     1  0 16:38 pts/1    00:00:00 sleep 300
jeroen    4475     1  0 16:38 pts/1    00:00:00 sleep 300
jeroen    4477     1  0 16:38 pts/1    00:00:00 sleep 300
jeroen    4479     1  0 16:38 pts/1    00:00:00 sleep 300
jeroen    4481     1  0 16:38 pts/1    00:00:00 sleep 300
jeroen    4483     1  0 16:38 pts/1    00:00:00 sleep 300
jeroen    4504  4195  0 16:39 pts/1    00:00:00 grep --color=auto sleep

更糟糕的是,它们的父进程ID为1,因此很难识别它们.是否有一种方法可以运行R脚本,该方法可以让我随时递归杀死该进程及其子进程?

To make things worse, their their parent process id is 1 making it hard to identify them. Is there a method to run an R script in a way that allows me to recursively kill the process and its children at any time?

所以我不想手动输入搜索&杀死进程.我也不想杀死所有的R进程,因为可能还有其他的进程做得很好.我需要一种方法来杀死特定进程及其所有子进程.

so I don't want to manually have to go in to search & kill processes. Also I don't want to kill all R processes, as there might be others that are doing fine. I need a method to kill a specific process and all of its children.

推荐答案

这主要是关于 multicore 部分的内容.孩子们正在等待您收集结果-请参见?collect.通常,切勿在没有提供清理的情况下使用parallel(通常在on.exit中). multicore 在诸如mclapply之类的高级函数中进行清理,但是如果您使用较低级的函数,则您有责任执行清理(因为 multicore 无法知道您是否让孩子们有意或无意地奔跑).

This is mainly about the multicore part. Children are waiting for you to collect the results - see ?collect. Normally, you should never use parallel without a provision to clean up, typically in on.exit. multicore cleans up in high-level functions like mclapply, but if you use lower-level functions it is your responsibility to perform the cleanup (since multicore cannot know if you left the children running intentionally or not).

您的示例确实是虚假的,因为您甚至不考虑收集结果.但是无论如何,如果这确实是您想要的,则必须在某个时候进行清理.例如,如果要在退出时终止所有子级,则可以这样定义.Last:

Your example is really bogus, because you don't even consider collecting results. But anyway, if that is really what you want, you'll have to do the cleanup at some point. For example, if you want to terminate all children on exit, you could define .Last like this:

 .Last <- function(...) {
     collect(wait=FALSE)
     all <- children()
     if (length(all)) {
         kill(all, SIGTERM)
         collect(all)
     }
 }

同样,以上不是推荐的处理方式-这只是最后的选择.您应该真正分配工作并收集诸如以下的结果

Again, the above is not a recommended way to deal with this - it rather a last resort. You should really assign jobs and collect results like

jobs <- lapply(1:3, function(i) parallel({Sys.sleep(i); i}))
collect(jobs)

对于一般流程子问题-init仅在R退出后才继承子级,但是在.Last中您仍然可以找到其pids,因为此时父进程存在,因此您可以执行与在 multicore 情况下.

As for the general process child question - init inherits the children only after R quits, but in .Last you can still find their pids since the parent process exists at that point so you could perform similar cleanup as in the multicore case.

这篇关于在Linux中递归地杀死带有子进程的R进程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆