Chinaunix首页 | 论坛 | 博客
  • 博客访问: 121101
  • 博文数量: 31
  • 博客积分: 2010
  • 博客等级: 大尉
  • 技术积分: 361
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-11 15:38
文章分类

全部博文(31)

文章存档

2008年(31)

我的朋友

分类: LINUX

2008-05-02 11:55:55

     今天完成了我Linux进程学习计划中的最后一个内容:进程的终止。

     先了解一下当我们或者系统终止一个进程的时候,Linux0.11内核是怎么处理的。当我们在程序中要退出这个程序的时候,会直接或者间接的调用exit()这个C库函数,这个库函数实际上执行linuxsys_exit()的系统调用,这个系统调用会调用内核的do_exit()函数完成大部分资源的释放、与此进程相关进程的处理,将此进程置成僵死状态,最后向父进程发送进程终止信号,并执行进程的调度;当这个父进程在某个时候系统调用返回的时候,会发现自己收到了进程终止的信号,就会释放这个子进程的进程数据结构,完成进程的完全释放。当然,父进程如果调用了waitpid()函数,也会完成子进程的完全释放。下面我就具体说一下do_exit()的具体工作过程:

1)  释放代码段和数据段所占的内存。

2)  处理其子进程:将子进程的父进程改为init进程,并判断如果子进程已经处于僵死状态,则向init进程(这些进程的新父进程)发送子进程终止信号。也就是说。

3)  释放pwdrooti节点。

4)  如果当前进程是会话头:释放终端;挂起该会话中的进程。

5)  将当前进程置为僵死状态。

6)  向父进程发送子进程终止信号。

7)  执行schedule()

在这里涉及到了两个函数,一个是6)中向父进程发送子进程终止信号的函数:tell_father();另一个是4)中挂起会话中进程的函数:kill_session()Tell_father()函数做的就是将当前进程的父进程的信号中的sigchld(子进程终止信号)位置位。Kill_session()做的就是,扫描系统的所有任务,如果哪个任务的session与当前进程的session相同,就将这个进程的的sighup信号位置位。

在这里我还要介绍一下也是与进程释放相关的系统调用:waitpid()。这个函数的主要功能是挂起当前进程,直到它所等待的进程终止或者僵死了,或者它需要调用某个信号句柄。它的参数pid指明了它等待的进程号,这个进程号不但可以指定哪个进程,还可以指定某些进程。大体工作过程是这样的:

1)  扫描系统的任务数组,当发现与传入的pid与扫描到的进程相符(不一定相同)的时候,就会做一下处理:

判断这进程的状态,如果是停止转状态,再根据传入的另一个参数option判断是立即返回还是继续扫描;如果是僵死状态,就释放该进程的任务数据结构task_struct

       2)如果扫描结束后,发现等待的进程没有处在停止或者僵死状态的,就根据option判断是返回还是继续等待。如果是继续等待则做一下工作:将此进程置位可中断的睡眠状态,并执行进程调度程序shedule(),在schedulue之后是当此进程被重新执行的时候的处理:如果自己除了sigchld这外没收到其它信号(是否需要调度信号处理句柄),就转向开头进行再一次的扫描,如果发现此时收到了信号,就返回系统调用中断出错码,用户针对这个出错号应该再继续调用本函数。

以上就是我对今晨终止的理解。至此,我对Linux0.11核进程部分的学习告一段落了,下面我打算开始内存管理的学习。

阅读(832) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~