源作者:编编成程
kill怎么运行程序
你可以用kill -9 / killall -9来杀死进程,但是你会发现实际上进程安装的sigaction()并不会对SIGKILL有任何反应(包括SIGSTOP),仔细来理解下内部的实现原理,对你的理解会有帮助,接下来我们就来一起学习一下,当给进程发送kill -9之后,内部会发生什么事情。
首先,你的进程不会收到任何的SIGKILL信号,因为这个信号已经被你的kernel以及操作系统给吃掉了。当你发送SIGKILL给对应的process之后,kernel的scheduler会立即停止给Process任何用户空间的时间片,当进程本身是多线程的话,scheduler也会把这些线程都stop掉(在单核上会更加容易)。当你的进程或者线程正在执行kernel code
(system call, I/O操作关于一段内存映射)的时候,这个时候要分具体情况:
有些系统调用是可以被中断的,这种情况下,内核会标记程序为dying状态,系统调用会正常调用,但是对于这些可中断的system call他们会在任何合适的stop points的地方进行check这个标记位,已经会比较早的退出
对于非可中断的系统调用,他们会一直运行直到完成,同时在返回到user-space之前check一下这个flag
当任何的kernel routines完成之后,process state会从dying变为dead, kerne就会开始做清理工作,这跟普通程序的退出是一样的。当clean-up做完之后,一个大于128的result code会返回(指示是被signal杀掉的), 程序接下来会把状态改成zombie. 这个情况下,这些进程的父进程会被通知同时接受到SIGCHLD
信号。
因此从结果上来说,process本身永远都没有机会去处理SIGKILL信号。同时当程序成为zombie状态,这表示程序其实已经死掉了,但是他的父进程还没有给acknowledge,这需要父进程通过wait()来读取dead process的Exit Code
.此时zombie process唯一浪费的资源就是在process table中关于他自身的PID,exit code以及其他一些关于他死亡时间的描述。
如果父进程在子进程之前就死了,那么这些孤儿进程会自动被PID #1接管(init), 这个进程会有责任和义务去call对应的wait()来保证这些孤儿进程不会成为zombies.如果此时你发现你的系统有很多的zombie process都没来得及清理,那么表示他们的父进程可能已经出现了问题。对于僵尸进程来说,如果出现大量这种情况,那么唯一的补救措施就是把他们的父进程也杀了