如果不允许程序处理或忽略 SIGKILL 和 SIGSTOP,并且必须立即终止,那么为什么内核还要向程序发送信号呢?内核不能简单地将程序从CPU和内存中逐出吗?我认为内核有能力直接执行此操作。
答案1
答案2
这回答部分正确,终止进程比释放内存要做更多的事情。然而,aSIGKILL
并不是拍拍肩膀或请求做某事,它是进程无法忽略或处理的少数信号之一。这意味着 aSIGKILL
始终由内核的默认处理程序处理,并且与大多数信号一样,此默认操作是终止接收信号的进程。程序的用户空间部分甚至看不到信号,因此不需要执行某些操作,不需要合作,因此程序在接收后不会出现任何行为不当SIGKILL
,无论是出于恶意还是由于某些编程错误。相反,进程的内核端将处理该信号并终止该进程。因此,在某种程度上,内核通过告诉内核的另一部分应终止进程来直接终止进程。
从编程的角度来看,当内核想要终止一个程序时(这主要是由于缺少资源,特别是没有足够的可用 RAM),有两种可能性,即在必须终止进程时复制执行此操作的代码,或者只调用一个函数来传递信号,并知道终止进程所需的一切都将被处理。第二种方法不仅减少了初始工作,而且从长远来看也意味着减少了工作量,因为不需要维护重复的代码。
答案3
概述信号如何工作,以完成其他非常好的答案:
进程的执行可以以两种模式发生:在用户空间或在内核空间。在用户空间中,进程执行其程序的代码,而在内核空间中,进程执行内核的代码。进程尽可能在用户空间中运行来完成其工作,但在执行过程中,当它们创建一个进程时,会不时地进入内核空间。系统调用(这对于系统本身的硬件或共享资源上的任何特权操作是必需的,例如读取文件)或者当它们在执行中被中断时。
处理信号有两种情况:当进程完成系统调用后返回到用户空间时,或者当它从系统调用中唤醒时。可中断的睡眠并恢复执行。在这两种情况下,进程都位于内核空间中。首先,内核检查进程是否有某个信号待处理并对其采取行动。例如,如果为信号定义了处理程序,它会使进程在返回用户空间时执行它。正如您自己所说,KILL 的情况很特殊,因为它无法被捕获。所以,对于内核来说,这实际上是一个简单的情况:返回用户空间被取消,进程立即被杀死,这意味着它不会再在用户空间执行任何代码,它的内存被释放,它的父进程被通知它的死亡等等。
答案4
退出时的进程会在其进程上下文/环境中执行一些清理操作,例如释放内存、释放信号量、关闭文件,可能还有一些统计信息。尽管内核可以复制这一点,但更容易轻拍进程并要求它自杀。