1.概述 在linux 中每一个进程都由task_struct 数据结构来定义. task_struct就是我们通常所说的PCB.她是对进程控制的唯一手段也是最有效的手段. 当我们调用fork() 时, 系统会为我们产生一个task_struct结构。然后从父进程,那里继承一些数据, 并把新的进程插入到进程树中, 以待进行进程管理。因此了解task_struct的结构对于我们理解任务调度(在linux 中任务和进程是同一概念)的关键。
在进行剖析task_struct的定义之前,我们先按照我们的理论推一下它的结构:
1、进程状态 ,将纪录进程在等待,运行,或死锁
2、调度信息, 由哪个调度函数调度,怎样调度等
3、进程的通讯状况
4、因为要插入进程树,必须有联系父子兄弟的指针, 当然是task_struct型
5、时间信息, 比如计算好执行的时间, 以便cpu 分配
6、标号 ,决定改进程归属
7、可以读写打开的一些文件信息
8、 进程上下文和内核上下文
9、处理器上下文
10、内存信息
因为每一个PCB都是这样的, 只有这些结构, 才能满足一个进程的所有要求。
详见
/include/linux/sched.h- struct task_struct {
- /* 进程状态*/
-
volatile long state; /*当前进程的状态,-1 unrunnable, 0 runnable, >0 stopped */
-
unsigned long flags; /进程标志*/
-
int lock_depth; /*大内核锁深度*/
-
unsigned long policy;/*进程优先级,进程每次获取CPU后可使用的时间(按jiffies计)*/
- struct list_head run_list;
-
unsigned long long timestamp;
-
int activated;
- unsigned long timeout, policy, rt_priority;/*重新唤醒时间,调度策略*/
-
cpumask_t cpus_allowed;
-
unsigned int time_slice, first_time_slice;
-
struct list_head tasks;
-
pid_t pid;
-
pid_t tgid;
-
struct task_struct *real_parent; /* real parent process (when being debugged) */
-
struct task_struct *parent; /* parent process */
-
struct list_head children; /* list of my children */
-
struct list_head sibling; /* linkage in my parent's children list */
-
struct task_struct *group_leader; /* threadgroup leader */
-
-
/* 信号处理*/
-
struct signal_struct *signal;
-
struct sighand_struct *sighand;
-
sigset_t blocked, real_blocked;
-
struct sigpending pending;
-
-
/* Thread group tracking */
-
u32 parent_exec_id;
-
u32 self_exec_id;
-
/* Protection of (de-)allocation: mm, files, fs, tty */
-
spinlock_t alloc_lock;
-
};
2.调度数据成员(1) volatile long states--表示进程的当前状态: TASK_RUNNING:正在运行或在就绪队列run-queue中准备运行的进程,实际参与进程调度。
TASK_INTERRUPTIBLE:处于等待队列中的进程,待资源有效时唤醒,也可由其它进程通过信号(signal)或定时中断唤醒后进入就绪队列run-queue。
TASK_UNINTERRUPTIBLE:处于等待队列中的进程,待资源有效时唤醒,不可由其它进程通过信号(signal)或定时中断唤醒。
TASK_ZOMBIE:表示进程结束但尚未消亡的一种状态(僵死状态)。此时,进程已经结束运行且释放大部分资源,但尚未释放进程控制块。
TASK_STOPPED:进程被暂停,通过其它进程的信号才能唤醒。导致这种状态的原因有二,或者是对收到SIGSTOP、SIGSTP、SIGTTIN或SIGTTOU信号的反应,或者是受其它进程的ptrace系统调用的控制而暂时将CPU交给控制进程。
TASK_SWAPPING:进程页面被交换出内存的进程。
(2) unsigned long flags--进程标志 PF_ALIGNWARN 打印“对齐”警告信息。
PF_PTRACED 被ptrace系统调用监控。
PF_TRACESYS 正在跟踪。
PF_FORKNOEXEC 进程刚创建,但还没执行。
PF_SUPERPRIV 超级用户特权。
PF_DUMPCORE dumped core。
PF_SIGNALED 进程被信号(signal)杀出。
PF_STARTING 进程正被创建。
PF_EXITING 进程开始关闭。
PF_USEDFPU 该进程使用FPU(SMP only)。
PF_DTRACE delayed trace (used on m68k)。
(3) long priority--进程优先级 Priority的值给出进程每次获取CPU后可使用的时间(按jiffies计)。优先级可通过系统调用
(4) unsigned long policy--该进程的进程调度策略 可以通过系统调用sys_sched_setscheduler()更改(见kernel/sched.c)。调度策略有:
SCHED_OTHER 0 非实时进程,基于优先权的轮转法(round robin)。
SCHED_FIFO 1 实时进程,用先进先出算法。
SCHED_RR 2 实时进程,用基于优先权的轮转法。
(5) unsigned long timeout--重新唤醒定时 用于软件定时,指出进程间隔多久被重新唤醒。采用tick为单位。
(6) pid_t pid和tpid--进行和线程ID号
pid_t类型通常定义为int,即可以使用2的32次方个不同ID
3.信号处理(1) unsigned long signal;
进程接收到的信号。每位表示一种信号,共32种。置位有效。
(2) unsigned long blocked;
进程所能接受信号的位掩码。置位表示屏蔽,复位表示不屏蔽。
参考文献1.linux-task_struct的结构注释.
2.
阅读(1198) | 评论(0) | 转发(0) |