我什么时候不应该杀死 -9 进程?

Mik*_*kel 419 linux command-line kill process-management

我总是很犹豫要不要跑kill -9,但我看到其他管理员几乎是例行公事。

我认为可能有一个明智的中间立场,所以:

  1. 何时以及为何应kill -9使用?什么时候,为什么不呢?
  2. 在做之前应该尝试什么?
  3. 什么样的调试“挂起”进程会导致进一步的问题?

gee*_*aur 386

通常,您应该在( )之前使用kill( 的缩写kill -s TERM,或在大多数系统上kill -15)让目标进程有机会在其之后进行清理。(进程不能 catch 或 ignore ,但他们可以并且经常会 catch 。)如果你不给进程一个机会来完成它正在做的事情并清理它,它可能会在它周围留下损坏的文件(或其他状态)重新启动后将无法理解。kill -9kill -s KILLSIGKILLSIGTERM

strace/ trussltrace并且gdb通常是查看卡住进程卡住原因的好主意。(truss -u在 Solaris 上特别有用;我发现ltrace经常以无法使用的格式向库调用提供参数。)Solaris 也有有用的/proc基于工具,其中一些已移植到 Linux。(pstack通常很有帮助)。

  • 令人信服的原因是,如果您养成发送 SIGKILL 的习惯,那么当您遇到一个程序时,例如,它会损坏您或您公司的重要数据库,您真的会后悔。`kill -9` 有它的用途,作为最后的终结者,强调最后的手段;在最后手段之前使用它的管理员 a) 不太了解成为管理员,并且 b) 不应该在生产系统上。 (76认同)
  • @dhruvbird:仅仅因为您的 DB 应该配备防弹背心,并不意味着您应该在不需要时射击它们。虽然您可能认为它不像 Arcege 所说的那样有风险,但我认为他的观点仍然是有风险的,应该是最后的手段。 (28认同)
  • @Arcege 你认为使用一个如果用 -9 杀死会破坏数据的数据库到底是一个值得使用的数据库吗?iirc、mysql、bdb、pg 等...当用 -9 杀死时都表现良好。 (15认同)
  • killall -9 java ftw (13认同)
  • @Mikel 通过它的另一件事,有时最好诱使应用程序使用 SIGQUIT 或 SIGSEGV 之类的信号来清理自己,如果它不响应 SIGINT/SIGTERM。例如,全屏 3-D 应用程序甚至 Xorg。使用 SIGQUIT,它不会有机会清理任何东西,而是欺骗它认为发生了段错误,它会觉得它别无选择,只能清理并退出。 (9认同)
  • @Arcege 我的意思是所有数据库(包括 sqlite)都维护单独的日志并维护这些日志的有效性,这样即使 db 文件损坏(比如由于读取不完整),日志也可以用来修复它。 (4认同)
  • @dhruvbird 使用 O_SYNC 打开文件描述符,然后使用 SIGKILL 将是安全的。在将缓冲区写入文件之前,任何其他操作都会导致文件被关闭。数据是否已损坏而无法修复,可能不会,但您不能使用 SIGKILL 说它不会损坏。行为不适应,风险仍然存在。为了回答您的问题,SIGKILL 适用于 _extreme_ 情况并且损坏是预期的风险,所以是的,任何在 SIGKILL 上损坏的东西都是可以接受的。 (3认同)
  • (免责声明:其中一些可能是 Linux 特定的。)我的进程通常是 SIGINT(即 ctrl-C,如果有控制台)、SIGQUIT(即 ctrl-\\)、SIGTERM,然后是 SIGKILL。请注意,即使使用 SIGKILL,某些进程也不会死亡。如果它在永远不会退出的系统调用中,它将永远不会收到该信号。检查顶部的 D 状态。另外,检查 dmesg。您可能会发现您遇到了内核错误,然后所有赌注都被取消了。我唯一一次直接使用 SIGKILL 是当进程有大量内存在交换时,然后 SIGKILL 将释放它而无需等待将其全部交换回来。 (2认同)
  • @Arcege db 文件修复不是一个单独的进程,而是进程重新启动时启动路由的一部分。通常,您会使用 daemontools 或类似工具不断监视您的守护程序。此外,修复文件不需要太多时间,因为它是日志重播,而不是像 fsck 那样昂贵的东西。事实上,在 HN 上有一个关于这个的讨论(dbs 应该处理 -9 并在此之后恢复事实)。 (2认同)

Sha*_*off 237

Randal Schwartz 过去经常在列表中发布“(x) 的无用使用”。一个这样的帖子是关于kill -9。它包括原因和要遵循的食谱。这是一个重建版本(引用如下)。

(引用可恶)

不不不。不要使用kill -9。

它没有给进程一个干净的机会:

1) 关闭套接字连接

2)清理临时文件

3)通知它的孩子它正在消失

4) 重置其终端特性

等等等等等等。

通常,发送 15,然后等待一两秒钟,如果这不起作用,则发送 2,如果不起作用,则发送 1。如果没有,请删除二进制文件,因为该程序表现不佳!

不要使用kill -9。不要为了整理花盆而拿出联合收割机。

只是 Usenet 的另一个无用用途,

(。签名)

  • 啊,是的,旧的“如果它在任何方面都不完美,那么使用它就是愚蠢的”论点。 (50认同)
  • 当进程终止时,操作系统不会关闭任何打开的文件描述符(包括套接字)吗? (14认同)
  • 是的,它会。但是假设您正在杀死连接客户端的服务器进程,那么客户端不会在超时之前注意到服务器已经消失。 (6认同)
  • 如果进程被杀死,则套接字将向对等方发送 RST,就像进程对套接字调用关闭或关闭一样,套接字将发送 FIN。不需要超时。只有掉电或拔掉网线才会出现超时情况。 (5认同)
  • 或者如果所讨论的过程是您公司的生产,则使用愚蠢 (3认同)
  • @BjörnLindqvist 你说的不是真的。当最后一个引用 TCP 套接字的文件描述符关闭时,内核将发送一个数据包告诉另一端连接已关闭。无论最后一个文件描述符是使用 close 系统调用、通过终止进程还是以其他方式关闭,都会发生这种情况。 (3认同)
  • 该链接不再有效;看起来它已被占用旧 URL 声誉的阴暗内容所接管。 (2认同)

小智 83

这样做应该总是可以的kill -9,就像通过拉电源线来关闭应该总是可以的一样。它可能是反社会的,需要做一些恢复,但它应该起作用,并且是不耐烦的强大工具。

我这样说是因为有人会首先尝试普通 kill (15),因为它确实给了程序一个机会进行一些清理——也许只是写入“退出 sig 15”的日志。但我不会接受任何关于 kill -9 上的不良行为的投诉。

原因是:很多客户都在做程序员更喜欢但又不喜欢的事情。Random kill -9 测试是一个很好且公平的测试场景,如果您的系统不处理它,则您的系统已损坏。

  • @Karel:您测试您的系统之后是否可以恢复,并清除在 SIGKILL 时正在处理的任何损坏的事务。 (18认同)
  • 做一个 `kill -9` 是不行的,就像拔掉插头是不行的一样。当然,在某些情况下您别无选择,但这应该是最后的手段。当然,拔掉电源线或 `kill -9` 应该不会产生不利影响,例如阻止应用程序或操作系统正确重启,但如果使用推荐的方式(`kill [-15]`)或定期关闭将有助于避免在您经常以这种方式中断程序和操作系统时可能发生的混乱。在任何情况下,无论代码稳健性如何,始终存在丢失数据的风险。 (8认同)
  • 我怀疑 Michael 所说的“OK”是指您的程序应该优雅地处理这种情况,并且能够在重新启动时进行某种形式的清理。例如,清理 PID 文件等等,而不是把它的玩具扔出婴儿车并拒绝启动。 (7认同)
  • 你如何测试“随机杀死-9”?当你得到 kill -9 时,你就完成了。 (2认同)
  • @gerryk他们确实应该,但问题是有些人会将这个答案视为“杀死-9的许可证”,无论情况和环境如何。这是一种不负责任的态度。 (2认同)

bor*_*rud 43

我使用 kill -9 的方式与将厨房用具扔进洗碗机的方式大致相同:如果厨房用具被洗碗机损坏了,那么我不想要它。

这同样适用于大多数程序(甚至数据库):如果我不能没有事情会失控杀了他们,我真的不希望使用它们。(如果您碰巧使用这些非数据库之一,鼓励您假装他们没有持久化数据:好吧,我想是时候开始考虑自己在做什么了)。

因为在现实世界中,东西随时可能因任何原因而下降。

人们应该编写能够容忍崩溃的软件。尤其是在服务器上。你应该学习如何设计假设事情会崩溃、崩溃等的软件。

桌面软件也是如此。当我想关闭浏览器时,通常需要 AGES 才能关闭。有没有我的浏览器需要做的应该超过最多几秒钟。当我要求它关闭时,它应该立即设法做到这一点。当它没有时,那么我们拉出 kill -9 并使其成功。

  • 我同意应该编写一个过程来容忍这种失败,但我认为这样做仍然是不好的做法。数据库将恢复,但它可能会检测到粗鲁的中止,然后在重新启动时触发重要的恢复检查。那么进程正在处理的请求呢?它们都会立即被切断,客户端可能有错误并且也会失败? (5认同)
  • 任何时候都不能被杀死的数据库不是一个适当可靠的数据库。如果您需要一致性,这是一个非常基本的要求。至于客户端:如果他们在连接中断时失控并损坏数据,那么他们的设计也很糟糕。解决服务丢失的方法是通过冗余和自动故障转移/重试策略。通常对于大多数系统来说,快速失败比试图恢复更可取。 (4认同)
  • @borud 它可能不是完美编写的软件,但它是人们一直使用的软件。什么样的系统管理员有幸选择编写完美的软件,甚至总是从突然中断中优雅地恢复?不多。我个人使用关闭脚本,并通过它启动/停止进程。如果他们不响应关闭脚本(它向进程发出正确的信号),我会杀死 -9。 (4认同)
  • 在工具方面,烹饪基本食物和更复杂的菜肴之间没有区别。区别在于厨师。(但是,如果你和我一样花时间做饭,你就会意识到坚固是厨房工具的最低要求,大多数向消费者出售厨房用品的人不会从好的工具中分辨出坏工具。) (2认同)
  • 所以你鼓励人们马虎,因为很难把事情做好?越来越多的软件运行在短暂的操作环境中。如果您编写的软件在未正确关闭时变得繁琐,您将很难说服雇主雇用您作为开发人员。 (2认同)

Edu*_*scu 10

在所有其他答案中都没有提到一个kill -9根本不起作用的情况,当一个进程<defunct>被杀死并且不能被杀死时:

如何杀死父进程为 init 的 <defunct> 进程?

什么是不存在的进程,为什么它不会被杀死?

所以,你尝试之前,kill -9一个<defunct>进程运行ps -ef,看他的父母是什么,并尝试-15(TERM)或-2(INT),最后-9在他的父(KILL)。

注意:有 什么ps -ef作用

后期编辑和警告:在杀死进程、它们的父进程或它们的子进程时要小心谨慎,因为它们可能会使文件打开或损坏、连接未完成、可能损坏数据库等,除非您知道kill -9进程的作用,仅将其用作最后的手段,如果你需要运行 kill 在使用之前使用上面指定的信号-9 (KILL)


dhc*_*dhd 7

随意终止进程并不是一帆风顺的:数据可能会丢失,设计不佳的应用程序可能会以微妙的方式破坏自身,如果不重新安装就无法修复......但这完全取决于知道什么是安全的,什么是不安全的给定的情况。以及会有什么风险。用户应该知道一个进程是什么,或者应该做什么,它的约束是什么(磁盘 IOPS,rss/swap),并且能够估计一个长时间运行的进程应该花费多少时间(比如文件复制, mp3 重新编码、电子邮件迁移、备份、[您最喜欢的时间在这里]。)

此外,发送SIGKILL到 pid 并不能保证杀死它。如果它卡在系统调用中或已经僵化(Zin ps),它可能会继续僵化。这通常是 ^Z 一个长时间运行的过程并且bg在尝试之前忘记的kill -9情况。一个简单的fg将重新连接 stdin/stdout 并可能解除对进程的阻塞,通常随后进程终止。如果它卡在其他地方或处于某种其他形式的内核死锁中,则只有重新启动才能删除该进程。(僵尸进程在SIGKILL被内核处理后已经死了(没有进一步的用户态代码将运行),通常有一个内核原因(类似于被“阻塞”等待系统调用完成)进程没有终止。)

此外,如果您想终止一个进程及其所有子进程,请养成kill使用否定 PID调用的习惯,而不仅仅是 PID 本身。不能保证SIGHUP,SIGPIPESIGINT其他信号在它之后清理,并且有一堆不知名的进程要清理(还记得杂种吗?)很烦人。

Bonus evil:kill -9 -1kill -9 1(不要以 root 身份执行任何一项操作,除非您想看看在丢弃的、不重要的 VM 上会发生什么)稍微更具破坏性


Han*_*ndy 6

永远不要做一个kill -9 1. 还要避免对某些进程(如 mount`)进行终止操作。当我必须杀死很多进程时(例如,一个 X 会话挂起,我必须杀死某个用户的所有进程),我会颠倒进程的顺序。例如:

ps -ef|remove all processes not matching a certain criteria| awk '{print $2}'|ruby -e '$A=stdin.readlines; A.reverse.each{|a| puts "kill -9 #{a}"}'|bash
Run Code Online (Sandbox Code Playgroud)

请记住,kill这不会停止进程并释放其资源。它所做的只是向进程发送一个 SIGKILL 信号;你可能会遇到一个挂起的进程。

  • 这个答案部分令人困惑,部分错误。`kill -9 1` 在大多数 unice 下被忽略。没有必要为 `mount` 避免使用 `kill -9`,但也没有任何意义。我不知道你所说的“颠倒进程的顺序”是什么意思。`kill -9` 确实会停止(例如,杀死)一个进程,而不会让它有机会抱怨,但是 [如果进程处于不可中断的系统调用中,则不会立即发生杀死](http:// unix.stackexchange.com/q/5642/885)。使用 `kill -9` 杀死进程确实会释放大部分资源,但[不是全部](http://unix.stackexchange.com/questions/8916/8927#8927)。 (8认同)

小智 5

为什么你不想kill -9正常进行进程

根据man 7 signal

信号 SIGKILL 和 SIGSTOP 无法被捕获、阻止或忽略。

这意味着接收这些信号中的任何一个的应用程序都无法“捕获”它们以执行任何关闭行为。

kill -9在运行进程之前应该做什么

您应该确保在向进程发送信号之前:

  1. 确保进程不忙(即做“工作”);向进程发送 akill -9本质上会导致该数据丢失。
  2. 如果该进程是无响应的数据库,请确保它已先刷新其缓存。某些数据库支持向进程发送其他信号以强制刷新其缓存。


DrB*_*eco 5

我创建了一个脚本来帮助自动解决此问题。

它基于我在stackoverflow上的一个非常相似的问题中的完整答案2

您可以在那里阅读所有解释。总而言之,我会推荐 just SIGTERMand SIGKILL,甚至SIGTERM, SIGINTand SIGKILL。不过,我在完整答案中给出了更多选项。

请随意从 github存储库下载(克隆)它来 Killgracely 1