问题描述
如果我们假设终止Linux中的一系列进程的最佳方法是什么?
What is the best way to terminate a family of processes in Linux, if we assume that:
- 在我们开始清理之前,家庭中的任意进程可能会被杀死/终止;结果,如果子进程没有终止,则其PPID将为1
- 流程可以更改流程组
我正在查看的特定场景是Bash,但是越通用的技术越好.
The particular scenario I'm looking at is Bash, but the more general technique, the better.
推荐答案
您可能希望在其他登录Shell中执行终止操作(最终通过脚本执行),以确保您不会意外停止/终止该Shell/脚本尝试在完成其工作之前进行整体杀死:)
You may want to perform the killing (eventually via a script) in a different login shell to ensure you're not accidentally stopping/killing the very shell/script attempting to do the overall killing before it completes its job :)
第一个关键策略是不直接终止进程,而是:
The first key strategy is to not directly terminate a process, but to:
- 只需先冻结"它(使用
kill -STOP< pid>
)以防止它产生其他子代(需要可靠地确定其子代,否则,您将错过本节中介绍的内容问与答: https://superuser.com/questions/927836/how-to-deal-with-a-memory-leaking-fork-bomb-on-linux/927967#927967 ) - 将其添加到要终止的进程列表中(以后)
- 找到孩子的名单
- 在孩子身上重复整个故事,重复一遍
- just "freeze" it first (with
kill -STOP <pid>
) to prevent it fromspawning other children (needed to reliably determine its children,otherwise you'll miss some as explained in thisQ&A:https://superuser.com/questions/927836/how-to-deal-with-a-memory-leaking-fork-bomb-on-linux/927967#927967) - add it to the list of processes to terminate (later)
- find the list of its children
- iterate the whole story on the children, rince repeat
一旦冻结了基于ppid的整个祖先树,就可以开始基于流程组进行定位和冻结祖先-只要更改了其流程组的流程的父级仍然存在,您仍可以可靠地确定这些流程组((因为它们的ppid未被更改))-将这些组添加到要被nuked的pgid列表中,并冻结您可能在上述组中找到的任何新的基于ppid的进程子树:
Once the entire ancestry tree based on ppid is frozen you can start locating and freezing ancestries based on process groups - you can still determine these process groups reliably as long as the parents of the processes which changed their process group are still alive (since their ppid is not changed) - add these groups to a list of pgids to be nuked and freeze any new ppid-based process subtrees you may find in these groups like above:
- 如果他们的父母还活着,他们应该已经被冻结它们在冻结的基于ppid的祖先树中
- 如果他们是孤儿,则在将整个pgid都弄掉后会被杀死
可以通过会话ID来发现相关进程,其方式与基于组ID的方式非常相似(除了kill需要由pid进行,因为kill cmd支持组ID而不是会话ID).
Related processes can be discovered by session ID in a manner very similar to the one based on group ID (except killing needs to be done by pid as the kill cmd supports a group ID but not a session ID).
找到潜在相关进程的另一种方法是通过它们的tty(如果有).但是要小心-他们可能不是您想要杀死的进程的后代,而是祖先或兄弟姐妹.在调查时,您仍然可以冻结以这种方式找到的基于ppid的子树和组-如果以后不需要杀死它们,可以随时将它们融化"(使用 kill -CONT
).
Another way to find potentially related processes would be by their tty, if they have one. But with care - they might not be descendents of the process you want to kill but ancestors or sibblings. You can still freeze the ppid-based subtrees and groups you find this way while you investigate - you can always "thaw" them later (with kill -CONT
) if they don't need to be killed.
我不知道如何找到由进程声明自己为会话领导者(从而更改其sid和pgid)的进程去耦的后代进程子树,如果他们的父母去世了并且没有怜悯之情.
I don't know how to locate descendant process subtrees decoupled by a processes declaring themselves session leaders (thus changing both their sid and pgid) if their parents died and they have no pty.
一旦整个子树列表被冻结,就可以根据需要杀死进程(通过pid或pgid杀死)或解冻它们以继续其工作.
Once the entire list of subtrees is frozen processes can be killed (by pid or pgid as needed) or thawed to continue their work if desired.
这篇关于终止一系列过程的最可靠方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!