进程删除

Unix允许进程查询内核以获得其父进程的PID,或者其任何于进程的执行状态。例如,进程可以创建一个子进程来执行特定的任务,然后调用诸如wait()这样的一些库函数检查子进程是否终止。如果子进程已经终止,那么,它的终止代号将告诉父进程这个任务是否已成功地完成。


为了遵循这些设计选择,不允许Unix内核在进程一终止后就丢弃包含在进程描述符字段中的数据。只有父进程发出了与被终止的进程相关的wait()类系统调用之后,才允许这样做。这就是引入僵死状态的原因:尽管从技术上来说进程已死,但必须保存它的描述符,直到父进程得到通知。


如果父进程在子进程结束之前结束会发生什么情况呢?在这种情况下,系统中会到处是僵死的进程,而且它们的进程描述符永久占据着RAM。如前所述,必须强迫所有的孤儿进程成为init进程的子进程来解决这个问题。这样,init进程在用wait()类系统调用检查其合法的子进程终止时,就会撤消僵死的进程。


release_task()函数从僵死进程的描述符中分离出最后的数据结构;对僵死进程的处理有两种可能方式;如果父进程不需要接收来自子进程的信号,就调用do_exit();如果已经给父进程发送了一个信号,就调用wait4()waitpid()系统调用。在后一种情况下,函数还将回收进程描述符所占用的内存空间,而在前一种情况下,内存的回收将由进程调度程序来完成。该函数执行下述步骤:

  1. 递减终止进程拥有者的进程个数。这个值存放在本章前面提到的user_struct结构中。

  2. 如果进程正在被跟踪,函数将它从调试程序的ptrace_children链表中删除,并让该进程重新属于初始的父进程。

  3. 调用__exit_signal()删除所有的挂起信号并释放进程的signal_struct描述符。如果该描述符不再被其它的轻量级进程使用,函数进一步删除这个数据结构。此外,函数调用exit_itimers()从进程中剥离掉所有的POSIX时间间隔定时器。

  4. 调用__exit_sighand()删除信号处理函数。

  5. 调用__unhash_process(),该函数依次执行下面的操作:

a.变量nr_threads减。

b.两次调用detach_pid(),分别从PIDTYPE_PIDPIDTYPE_TGID类型的PID散列表中删除进程描述符。

c.如果进程是线程组的领头进程,那么再调用两次detach_pid(),PIDTYPE_PGIDPIDTYPE_SID类型的散列表中删除进程描述符。

d.用宏REMOVE_LINKS从进程链表中解除进程描述符的链接。

  1. 如果进程不是线程的领头进程,领头进程处于僵死状态,而且进程是线程组的最后一个成员,则该函数向领头进程的父进程发送一个信号,通知它进程已终止。

  2. 调用sched_exit()函数来调整父进程的时间片。

  3. 调用put_task_struct()递减进程描述符的使用计数器,如果计数器变为0,则函数终止所有残留的对进程的引用。

a.递减进程所有都的user_struct数据结构的使用计数器,如果使用计数器变成0,就释放该数据结构。

b.释放进程描述符以及thread_info描述符和内核堆栈所占用的内存区域。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值