我见过很多流程经理尝试这样做。据我了解,您应该只使用 SIGTERM 来终止进程。该进程可能需要未知的时间来自行清理;在缓慢的系统上,可能需要几分钟的时间。我一直认为唯一的解决办法就是耐心等待程序清理并优雅退出。如果进程没有捕获 SIGTERM,则这是一个错误,应报告给软件的维护人员。
我见过像 docker 这样的流行工具也尝试这样做:
用法: docker stop [选项] CONTAINER [CONTAINER...]
停止正在运行的容器(发送 SIGTERM,然后在宽限期后发送 SIGKILL)
这是不好的做法吗?我还好奇的一件事是关闭过程如何在 SystemV 风格的 init 系统上工作。我查看了一些手册页和其他一些问题,但找不到明确的答案。我猜测每个初始化服务(术语?)都会看到运行级别的变化并执行初始化脚本中定义的正确的“停止”函数。它是否会逐一执行此操作,确保每项服务正确结束?未由 init 脚本处理的进程会发生什么情况?我看到一些问题模糊地提到了在 SIGKILL 之前使用的宽限期,但我希望有人能够详细说明或至少为我指出正确的方向。 :)
如果有人可以帮助我了解更多关于 systemd 的工作原理,我很乐意研究并了解更多信息。我查看了手册页,但也找不到任何明确的信息。
答案1
你可以选择吃蛋糕,也可以吃掉它。程序希望有足够长的时间来对 SIGTERM 做出反应。系统(程序管理器)希望能够终止。如果系统永远等待,则允许程序通过从不响应来劫持系统关闭(因为该程序是恶意的或因为它有错误)。
在正常的关闭序列中,每个守护进程都通过守护进程的作者或打包者提供的 init 脚本(如果需要,可以将其称为关闭脚本)终止。根据守护进程的不同,init 脚本可能只向其发送一个信号,也可能执行更受控制的关闭(例如,通过写入套接字)。 init 脚本可能会等待守护进程报告它已圆满关闭,或者可能会强行终止它。初始化脚本以 root 身份运行(它们可能会以su
权限较低的用户身份调用来执行部分任务);他们应该是合作的,所以他们可以让系统永远挂起。
一旦初始化脚本完成其工作,所有服务都应该关闭。任何剩余的进程都应该是不重要的或行为不当的。因此,在这个阶段,剩余的进程被告知关闭(SIGTERM),并且在宽限期(给它们最后一次彻底关闭的机会)之后,系统必须关闭,以便强行终止任何剩余的进程(SIGKILL)。
将初始化脚本视为正常的逮捕程序 - 出示逮捕令、大声警告等。守法的守护进程应该在此时关闭,尽管守护进程有律师(初始化脚本),只要他们想。一旦正常进程完成,剩余的守护进程就被认为是敌对的。系统发出警告信号 (SIGTERM),然后在延迟后发出 SIGKILL。