lionel chang

导航

从task_struct开始学习linux内核

一。数据结构

进程控制块PCB(Process Control Block)是进程存在和运行的唯一标志,在Linux中用task_struct这个结构体来表示。这个结构体中有很多数据项,查看源代码时没必要理解全部的数据项,只需要在以后使用时再理解。

struct task_struct
{
      ....
};

下面重点介绍几个基本的数据项:

1。进程状态

task_struct中用一个长整形state表示进程的状态。

volatile long state;

在linux中有四种基本的进程状态:

(1)就绪态(TASK_RUNNING):包括了运行态的进程。这是为了方便管理,因为任意时刻处于就绪态的进程最多只有一个。

(2)等待(睡眠)态:又被分为两种

      i.浅度睡眠态(TASK_INTERRUPTIBLE): 在两种情况下被唤醒:

                                                         1.当等待的资源满足时。

                                                         2.其它进程通过信号或时钟中断唤醒。

     ii.深度睡眠态(TASK_UNINTERRUPTIBLE):只能等到等待的资源满足时才被唤醒,而不能被其它进程唤醒

 (3)暂停状态(TASK_STOPPED):收到以下几种信号,进程进入暂停状态:

        i.SIGSTOP------------------停止进程执行

        ii。SIGTSTP-----------------从终端发来信号停止进程

       iii。SIGTTIN------------------来自键盘的中断

       iv。SIGTTOU----------------后台进程请求输出。

(4)僵死状态(TASK_ZOMBIE):进程已结束且释放大部分资源,但尚未释放其PCB

2。进程标识符

linux用一个32位无符号整形pid来简单的标识一个进程,用uid和gid分别来标识进程所属的用户和组

pid_t pid;      
uid_t uid;
gid_t gid;

pid的上限是由pid_max决定的。编译内核时会让选择0x1000和0x8000两种数值,即pid_max=4096和pid_max=32768两种。

3。亲属关系

struct list_head children;        //子进程链表
struct list_head sibling;        //兄弟进程链表
struct task_struct *real_parent; //真正创建当前进程的进程 
struct task_struct *parent;      //养父进程
二。进程控制块的存放

1.内核栈

当进程从用户态进入内核态时要使用位于内核数据段上的内核栈,

2.数据结构

union thread_union
{
         struct thread_info thread_info;
         unsigned long stack[THERAD_SIZE/sizeof(long)];//内核栈,一般为8KB
};

内核中将task_struct的指针放在thread_info结构体中,而这个结构体又与内核栈一块被放在8KB的内核空间thread_union中。

struct thread_info{  
          struct task_struct *task;  
          struct exec_domain *exec_domain;  
          .....  
};  

posted on 2012-08-21 16:27  woshizyl  阅读(208)  评论(0编辑  收藏  举报