ARM Linux 源码分析系列文章基于 Linux 2.6.22 讲解,转载请标明原处!
一个进程可以使用exit系统调用来结束自己并进入僵死状态。他最后在内核中执行到的函数为sys_exit()。
他调用do_exit()来执行真正的操作,实际上do_exit()涉及到很多其他内容,所以我们只讲解部分最为关键的代码,下面分析一下do_exit()函数。
847行,取出要结束的进程(也就是当前进程)的进程描述符。
874行,in_interrupt()函数用来判断当前是否正在执行中断服务处理程序。exit()系统调用只能结束进程(线程),那么中断服务程序调用他是想结束谁呢?我们并不知道,因为我们并不知道中断会在什么时候发生,所以这里不允许在执行中断服务程序时调用到本函数。
876行,进程号(PID)为0的进程是idle进程,这个进程是系统中没有其他进程在执行时执行的函数,他不能被杀死。
879~882行,不允许杀死init进程。
887~889行,如果当前进程被跟踪且他需要报告给跟踪进程自己正在执行exit系统调用,那么就在888行把退出信号存放到ptrace_message字段,并在889行调用ptrace_notify()来通知跟踪进程我正在执行exit系统调用。
893行,如果当前进程在调用exit系统调用前已经正在执行删除操作了,那么就设置PF_EXITPIDONE 标志,并把当前进程的状态设为不可中断的暂停状态,这样他就不会再执行了,最后调度出去。
905行,设置PF_EXITING标志说明当前进程正在执行exit系统调用。
914~917行,只有线程的进程描述符的mm字段才为空,所以这里是:如果他是一个进程,那么就更新他的内存描述符。
918行,信号描述符是可以被进程共享的(比如说一个线程组内的所有进程都共享一个信号描述符),其共享的进程数存放在live字段里,而tsk进程都要被终结了,自然要递减他,说明少了一个使用这个描述符的进程。
919~922行,如果918行的live字段减为0了,就说明没有进程使用这个信号描述符了,那么剥离信号描述符中的所有定时器。