日期:2014-05-16  浏览次数:20916 次

linux内核--进程管理(一)
进程和线程的概念我就不讲了。总之,你记着:内核调度的对象是线程,而不是进程。linux系统中的线程很特别,它对线程和进程并不做特别区分。进程的另外一个名字叫任务(task).我和作者一样,习惯了把用户空间运行的程序叫做进程,把内核中运行的程序叫做任务。

      内核把进程存放在叫做任务队列(task list)的双向循环链表中,链表中的每一项都是类型为task_struct,名称叫做进程描述符(process descriptor)的结构,该结构定义在include/linux/sched.h文件中,它包含了一个具体进程的所有信息。

      linux通过slab分配器分配task_struct结构,这样能达到对象复用和缓存着色的目的。在2.6以前的内核中,各个进程的task_struct存放在它们内核栈的尾端。由于现在用slab分配器动态生成task_struct,所以只需在栈底或栈顶创建一个新的结构(struct thread_info),他在asm/thread_info.h中定义,需要的请具体参考。每个任务中的thread_info结构在它的内核栈中的尾端分配,结构中task域存放的是指向该任务实际task_struct指针。

      在内核中,访问任务通常需要获得指向其task_struct指针。实际上,内核中大部分处理进程的代码都是通过task_struct进行的。通过current宏查找到当前正在执行的进程的进程描述符就显得尤为重要。在x86系统上,current把栈指针的后13个有效位屏蔽掉,用来计算thread_info的偏移,该操作通过current_thread_info函数完成,汇编代码如下:

movl $-8192, %eax

andl  %esp, %eax

    最后,current再从thread_info的task域中提取并返回task_struct的值:current_thread_info()->task;

     进程描述符中的state域描述了进程的当前状态。系统中的每个进程都必然处于五种进程状态中的一种,什么运行态啦,阻塞态啦,它们之间转化的条件啦等等,这一点我也不细说了,为啥?随便一本操作系统的书里,讲得都比我好,要讲就要讲别人讲不好的,是不?现在我关心的问题是:当内核需要调整某个进程的状态时,该怎么做?这时最好使用set_task_state(task, state)函数,该函数将指定的进程设置为指定的状态,必要的时候,它会设置内存屏蔽来强制其他处理器作重新排序。(一般只有在SMP系统中有此必要)否则,它等价于:task->state = state; 另外set_current_state(state)和set_task_state(current, state)含义是等价的。

     一般程序在用户空间执行。当一个程序执行了系统调用或者触发了某个异常,它就陷入内核空间。系统调用和异常处理程序是对内核明确定义的接口,进程只有通过这些接口才能陷入内核执行----对内核的所有访问都必须通过这些接口。

     linux进程之间存在一个明显的继承关系。所有的进程都是PID为1的init进程的后代,内核在系统启动的最后阶段启动init进程。该进程读取系统的初始化脚本并执行其他的相关程序,最终完成系统启动的整个过程。

     系统中的每个进程必有一个父进程,每个进程也可以拥有一个或多个子进程。进程既然有父子之称,当然就有兄弟之意了。每个task_struct都包含一个指向其父进程task_struct且叫做parent的指针,同时包含一个称为children的子进程链表。所以访问父进程:struct task_struct *task = current->parent;按照如下方式访问子进程:

struct task_struct *task;
struct list_head *list;
list_for_each(list, &current->children){
           task = list_entry(list, struct task_struct, sibling);
}

      其中init进程描述符是作为init_task静态分配的。通过上面的init进程,父子进程关系,兄弟进程关系以及进程描述符的结构,我们可以得到一个惊人的事实:可以通过这种关系从系统的任何一个进程出发查找到任意指定的其他进程。而且方式还挺多的,这个就看书了,内容挺多我就不说了,只是最后需要指出的是,在一个拥有大量进程的系统中通过重复来遍历所有的进程是非常耗费时间的,因此,如果没有充足的理由千万别这样做。爱要一万个理由,这么做呢,没看出来.