1.当一个进程结束了运行或在半途中终止了运行,那么内核就需要释放该进程所占用的系统资源。这包括进程运行时打开的文件、申请的内存等。
2.当一个用户程序调用 exit() 系统调用时,就会执行内核函数 do_exit() 。
3. do_exit() 函数会首先释放进程代码段和数据段占用的内存页面,关闭进程打开着的所有文件,对进程使用的当前工作目录、根目录和运行程序的 i 节点进行同步操作。
4.如果进程有子进程,则让 init 进程作为其所有子进程的父进程。如果进程是一个会话头进程并且有控制终端,则释放控制终端,并向属于该会话的所有进程发送挂断信号 SIGHUP ,这通常会终止该会话中的所有进程
5.然后把进程状态置为僵死状态 TASK_ZOMBIE 。并向其原父进程发送 SIGCHLD 信号,通知其某个子进程已经终止。
6.最后 do_exit() 调用调度函数去执行其它进程。由此可见在进程被终止时,它的任务数据结构仍然保留着。因为其父进程还需要使用其中的信息。
7.在子进程在执行期间,父进程通常使用 wait() 或 waitpid() 函数等待其某个子进程终止。
8.当等待的子进程被终止并处于僵死状态时,父进程就会把子进程运行所使用的时间累加到自己进程中。最终释放已终止子进程任务数据结构所占用的内存页面,并置空子进程在任务数组中占用的指针项。
今天刚好查了一下,补充点点…
kill -HUP [pid]
killall -HUP [process-name]
kill -1 [pid]
killall -1 [process-name]
因此,你可以使用PID或者名称,信号名称或者号码。那么为什么要这样做而不使用/etc/init.d/foo命令重新启动呢?使用它们自己的 init(初始化)文件来控制服务是优先选择的方式,因为这些文件通常包含健全和错误检查以及额外的功能。使用“kill”命令和信号的主要原因是尽可能明确地终止挂起和失控的进程,而不必重新启动或者登出。
常用sudo kill -s 9 "pid"可以避免假死后重启电脑