为什么内核甚至懒得发送 SIGKILL?

kpj*_*shi 8 kernel signals

如果程序不允许处理或忽略 SIGKILL 和 SIGSTOP,并且必须立即终止,为什么内核还要向程序发送信号?内核不能简单地从 CPU 和内存中驱逐程序吗?我假设内核有能力直接做到这一点。

Ste*_*itt 17

终止的进程的用户空间部分SIGKILL永远不会知道它;内核处理一切。(这确实意味着某些资源可能会泄漏:临时文件、共享内存分配、由另一个进程(例如 X 服务器)代表已终止进程持有的资源……)

然而,信号仍然需要传递,以便其他进程可以找出被杀死的进程是如何终止的。使用 的父级wait将获得终止进程被终止的信息SIGKILL。

  • 同样,程序可能拥有内核不知道的更高级别的资源。例如,应用程序可能拥有一个未提交的数据库事务。最终,数据库服务器会放弃并回滚它(可能在 TCP 连接超时后不久),但在此之前,它会占用资源,甚至可能会因为写锁而阻止数据库服务器处理其他事务。 (4认同)
  • @1026501 某些类型的资源,如临时文件或 SysV 共享内存,内核无法自动清理。如果该过程没有机会自行删除它们,它们将留在 SIGKILL 上。 (3认同)

Ral*_*edl 3

这个答案部分正确,终止进程比释放内存有更多的工作要做。然而,aSIGKILL并不是拍拍肩膀或请求做某事,它是进程无法忽略或处理的少数信号之一。这意味着 aSIGKILL始终由内核的默认处理程序处理,并且与大多数信号一样,此默认操作是终止接收信号的进程。程序的用户空间部分甚至看不到信号,因此不需要执行某些操作,不需要合作,因此程序在接收后不会出现任何行为不当SIGKILL,无论是出于恶意还是由于某些编程错误。相反,进程的内核端将处理该信号并终止该进程。因此,在某种程度上,内核通过告诉内核的另一部分应终止进程来直接终止进程。

从编程的角度来看,当内核想要终止一个程序时(这主要是由于缺少资源,特别是没有足够的可用 RAM),有两种可能性,即在必须终止进程时复制执行此操作的代码,或者只调用一个函数来传递信号,并知道终止进程所需的一切都将被处理。第二种方法不仅减少了初始工作,而且从长远来看也意味着减少了工作量,因为不需要维护重复的代码。