您的位置:首页 > 运维架构 > Linux

Linux下PCB的task_struck结构体

2017-02-17 22:26 302 查看
在linux中,把每一个进程的基本信息抽象成一个结构体,这就是task_struct结构体,在include\linux\sched.h文件中定义。

一说到进程,就要想到task_struct结构体。每个进程都会被分配一个task_struct结构,它包含了这个进程的所有信息。在任何时候,操作系统都能跟踪这个结构的信息。

struct task_struct {

volatile long state;

/ /这个是进程的运行时状态,-1代表不可运行,0代表可运行,>0代表已停止。

可运行状态 TASK_RUNNING

处于这种状态的进程,要么正在运行、要么正准备运行。正在运行的进程就是当前进程(由current所指向的进程),而准备运行的进程只要得到CPU就可以立即投入运行,CPU是这些进程唯一等待的系统资源。系统中有一个运行队列(run_queue),用来容纳所有处于可运行状态的进程,调度程序执行时,从中选择一个进程投入运行。在后面我们讨论进程调度的时候,可以看到运行队列的作用。当前运行进程一直处于该队列中,也就是说,current总是指向运行队列中的某个元素,只是具体指向谁由调度程序决定。

等待状态 TASK_INTERRUPTIBLE可中断 TASK_UNINTERRUPTIBLE不可中断

处于该状态的进程正在等待某个事件(event)或某个资源,它肯定位于系统中的某个等待队列(wait_queue)中。Linux中处于等待状态的进程分为两种:可中断的等待状态和不可中断的等待状态。处于可中断等待态的进程可以被信号唤醒,如果收到信号,该进程就从等待状态进入可运行状态,并且加入到运行队列中,等待被调度;而处于不可中断等待态的进程是因为硬件环境不能满足而等待,例如等待特定的系统资源,它任何情况下都不能被打断,只能用特定的方式来唤醒它,例如唤醒函数wake_up()等。

暂停状态TASK_STOPPED

此时的进程暂时停止运行来接受某种特殊处理。通常当进程接收到SIGSTOP、SIGTSTP、SIGTTIN或 SIGTTOU信号后就处于这种状态。例如,正接受调试的进程就处于这种状态。

僵死状态TASK_ZOMBIE

进程虽然已经终止,但由于某种原因,父进程还没有执行wait()系统调用,终止进程的信息也还没有回收。顾名思义,处于该状态的进程就是死进程,这种进程实际上是系统中的垃圾,必须进行相应处理以释放其占用的资源

unsigned int flags;

/*

flags是进程当前的状态标志,具体的如:

0x00000002表示进程正在被创建;

0x00000004表示进程正准备退出;

0x00000040 表示此进程被fork出,但是并没有执行exec;

0x00000400表示此进程由于其他进程发送相关信号而被杀死 。

*/

unsigned int rt_priority;

//表示此进程的运行优先级

struct list_head tasks;

//这里出现了list_head结构体,详情请参考

struct mm_struct *mm;

//这里出现了mm_struct 结构体,该结构体记录了进程内存使用的相关情况,详情请参考

/* 接下来是进程的一些状态参数*/

int exit_state;

int exit_code, exit_signal;

//这个是进程号

pid_t pid;

//这个是进程组号

pid_t tgid;

//real_parent是该进程的”亲生父亲“,不管其是否被“寄养”。

struct task_struct *real_parent;

//parent是该进程现在的父进程,有可能是”继父“

struct task_struct *parent;

//这里children指的是该进程孩子的链表,可以得到所有孩子的进程描述符,但是需使用list_for_each和list_entry,list_entry其实直接使用了container_of,详情请参考

struct list_head children;

//同理,sibling该进程兄弟的链表,也就是其父亲的所有孩子的链表。用法与children相似。

struct list_head sibling;

//这个是主线程的进程描述符,也许你会奇怪,为什么线程用进程描述符表示,因为linux并没有单独实现线程的相关结构体,只是用一个进程来代替线程,然后对其做一些特殊的处理。

struct task_struct *group_leader;

//这个是该进程所有线程的链表。

struct list_head thread_group;

//顾名思义,这个是该进程使用cpu时间的信息,utime是在用户态下执行的时间,stime是在内核态下执行的时间。

cputime_t utime, stime;

//下面的是启动的时间,只是时间基准不一样。

struct timespec start_time;

struct timespec real_start_time;

//comm是保存该进程名字的字符数组,长度最长为15,因为TASK_COMM_LEN为16。

char comm[TASK_COMM_LEN];

/* 文件系统信息计数*/

int link_count, total_link_count;

/*该进程在特定CPU下的状态*/

struct thread_struct thread;

/* 文件系统相关信息结构体*/

struct fs_struct *fs;

/* 打开的文件相关信息结构体 */

struct files_struct *files;

/* 信号相关信息的句柄*/

struct signal_struct *signal;

struct sighand_struct *sighand;

/*这些是松弛时间值,用来规定select()和poll()的超时时间,单位是纳秒nanoseconds */

unsigned long timer_slack_ns;

unsigned long default_timer_slack_ns;

};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: