haikun he Asked: 2018-12-04 01:04:35 +0800 CST2018-12-04 01:04:35 +0800 CST 2018-12-04 01:04:35 +0800 CST 程序在发送 SIGKILL 信号时会做什么? 772 当我用来killall -9 name杀死一个程序时,状态变成了僵尸。几分钟后,它真的停了下来。那么,在那几分钟内发生了什么? kill signals 1 个回答 Voted Best Answer telcoM 2018-12-04T02:27:59+08:002018-12-04T02:27:59+08:00 该程序实际上从未收到 SIGKILL 信号,因为 SIGKILL 完全由操作系统/内核处理。 当发送特定进程的 SIGKILL 时,内核的调度程序会立即停止为该进程提供更多 CPU 时间来运行用户空间代码。如果在调度程序做出此决定时,进程有任何线程在其他 CPU/内核上执行用户空间代码,则这些线程也将停止。(在单核系统中,这过去要简单得多:如果系统中唯一的 CPU 内核正在运行调度程序,那么根据定义,它不会同时运行进程!) 如果进程/线程在 SIGKILL 时正在执行内核代码(例如系统调用,或与内存映射文件关联的 I/O 操作),它会变得有点棘手:只有一些系统调用是可中断的,所以内核在内部将进程标记为处于特殊的“死亡”状态,直到系统调用或 I/O 操作得到解决。解决这些问题的 CPU 时间将照常安排。可中断的系统调用或 I/O 操作将检查调用它们的进程是否在任何合适的停止点死亡,并在这种情况下提前退出。不间断的操作将运行完成,并在返回用户空间代码之前检查“死亡”状态。 一旦解决了任何进程内内核例程,进程状态就会从“死亡”变为“死”,并且内核开始清理它,类似于程序正常退出时。清理完成后,将分配一个大于 128 的结果代码(表示该进程已被信号杀死;有关混乱的详细信息,请参见此答案),并且该进程将转换为“僵尸”状态. 被杀死进程的父进程将收到一个 SIGCHLD 信号通知。 结果,进程本身永远不会有机会实际处理它收到的 SIGKILL 信息。 当进程处于“僵尸”状态时,意味着该进程已经死亡,但其父进程尚未通过使用wait(2)系统调用读取死进程的退出代码来确认这一点。基本上,僵尸进程消耗的唯一资源是进程表中的一个槽,该槽保存它的 PID、退出代码和进程在其死亡时的一些其他“重要统计信息”。 如果父进程在其子进程之前死亡,则孤立的子进程会自动被 PID #1 采用,它有一个特殊的职责是继续调用wait(2),这样任何孤立的进程就不会像僵尸一样留下来。 如果僵尸进程需要几分钟才能清除,则表明僵尸的父进程正在挣扎或没有正常工作。 在类 Unix 操作系统中出现僵尸问题时,有一个半开玩笑的描述:“你不能为僵尸本身做任何事情,因为它们已经死了。相反,杀死邪恶的僵尸大师! ” (即麻烦僵尸的父进程)
该程序实际上从未收到 SIGKILL 信号,因为 SIGKILL 完全由操作系统/内核处理。
当发送特定进程的 SIGKILL 时,内核的调度程序会立即停止为该进程提供更多 CPU 时间来运行用户空间代码。如果在调度程序做出此决定时,进程有任何线程在其他 CPU/内核上执行用户空间代码,则这些线程也将停止。(在单核系统中,这过去要简单得多:如果系统中唯一的 CPU 内核正在运行调度程序,那么根据定义,它不会同时运行进程!)
如果进程/线程在 SIGKILL 时正在执行内核代码(例如系统调用,或与内存映射文件关联的 I/O 操作),它会变得有点棘手:只有一些系统调用是可中断的,所以内核在内部将进程标记为处于特殊的“死亡”状态,直到系统调用或 I/O 操作得到解决。解决这些问题的 CPU 时间将照常安排。可中断的系统调用或 I/O 操作将检查调用它们的进程是否在任何合适的停止点死亡,并在这种情况下提前退出。不间断的操作将运行完成,并在返回用户空间代码之前检查“死亡”状态。
一旦解决了任何进程内内核例程,进程状态就会从“死亡”变为“死”,并且内核开始清理它,类似于程序正常退出时。清理完成后,将分配一个大于 128 的结果代码(表示该进程已被信号杀死;有关混乱的详细信息,请参见此答案),并且该进程将转换为“僵尸”状态. 被杀死进程的父进程将收到一个 SIGCHLD 信号通知。
结果,进程本身永远不会有机会实际处理它收到的 SIGKILL 信息。
当进程处于“僵尸”状态时,意味着该进程已经死亡,但其父进程尚未通过使用
wait(2)
系统调用读取死进程的退出代码来确认这一点。基本上,僵尸进程消耗的唯一资源是进程表中的一个槽,该槽保存它的 PID、退出代码和进程在其死亡时的一些其他“重要统计信息”。如果父进程在其子进程之前死亡,则孤立的子进程会自动被 PID #1 采用,它有一个特殊的职责是继续调用
wait(2)
,这样任何孤立的进程就不会像僵尸一样留下来。如果僵尸进程需要几分钟才能清除,则表明僵尸的父进程正在挣扎或没有正常工作。
在类 Unix 操作系统中出现僵尸问题时,有一个半开玩笑的描述:“你不能为僵尸本身做任何事情,因为它们已经死了。相反,杀死邪恶的僵尸大师! ” (即麻烦僵尸的父进程)