标识符
pid_t pid; //进程的唯一标识
pid_t tgid; // 线程组的领头线程的pid成员的值
pid是进程的唯一表示,范围是0~32767,可以表示32768个进程。
在Linux系统中,一个线程组的所有线程使用和该线程组的领头线程相同的PID,并被存放在tgid成员中。(线程是程序运行的最小单位,进程是程序运行的基本单位。)
进程状态
- 进程亲属关系
/*
1. pointers to (original) parent process, youngest child, younger sibling,
2. older sibling, respectively. (p->father can be replaced with
3. p->real_parent->pid)
*/
struct task_struct __rcu *real_parent; //real parent process
struct task_struct __rcu *parent; /* recipient of SIGCHLD, wait4() reports */
/*
4. children/sibling forms the list of my natural children
*/
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 */
在Linux系统中,所有进程之间都有着直接或间接地联系,每个进程都有其父进程,也可能有零个或多个子进程。拥有同一父进程的所有进程具有兄弟关系。
字段 | 描述 |
---|---|
real_parent | 指向其父进程,如果创建它的父进程不再存在,则指向PID为1的init进程 |
parent | 指向其父进程,当它终止时,必须向它的父进程发送信号。它的值通常与real_parent相同 |
children | 示链表的头部,链表中的所有元素都是它的子进程 |
sibling | 用于把当前进程插入到兄弟链表中 |
group_leade | 指向其所在进程组的领头进程 |
task_struct结构:
在进行剖析task_struct的定义之前,我们先按照我们的理论推一下它的结构:
1、进程状态 ,将纪录进程在等待,运行,或死锁
2、调度信息, 由哪个调度函数调度,怎样调度等
3、进程的通讯状况
4、因为要插入进程树,必须有联系父子兄弟的指针, 当然是task_struct型
5、时间信息, 比如计算好执行的时间, 以便cpu 分配
6、标号 ,决定改进程归属
7、可以读写打开的一些文件信息
8、 进程上下文和内核上下文
9、处理器上下文
10、内存信息
因为每一个PCB都是这样的, 只有这些结构, 才能满足一个进程的所有要求。
long state //任务的运行状态(-1 不可运行,0 可运行(就绪),>0 已停止)。
long counter //任务运行时间计数(递减)(滴答数),运行时间片。
long priority //运行优先数。任务开始运行时counter = priority,越大运行越长。
long signal //信号。是位图,每个比特位代表一种信号,信号值=位偏移值+1。
struct sigaction sigaction[32] //信号执行属性结构,对应信号将要执行的操作和标志信息。
long blocked //进程信号屏蔽码(对应信号位图)。
- (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计)。优先级可通过系统调用sys_setpriorty改变(在 kernel/sys.c中)。
(4) unsigned long rt_priority;
rt_priority 给出实时进程的优先级,rt_priority+1000给出进程每次获取CPU后可使用的时间(同样按jiffies计)。实时进程的优先级可通过系统 调用sys_sched_setscheduler()改变(见kernel/sched.c)。
(5) long counter;
在轮转法调度时表示进程当前还可运行多久。在进程开始运行是被赋为priority的值,以后每隔一个tick(时钟中断)递减1,减到0时引起新一轮调 度。重新调度将从run_queue队列选出counter值最大的就绪进程并给予CPU使用权,因此counter起到了进程的动态优先级的作用 (priority则是静态优先级)。
(6) unsigned long policy;
该进程的进程调度策略,可以通过系统调用sys_sched_setscheduler()更改(见kernel/sched.c)。调度策略有:
*SCHED_OTHER 0 非实时进程,基于优先权的轮转法(round robin)。
*SCHED_FIFO 1 实时进程,用先进先出算法。
*SCHED_RR 2 实时进程,用基于优先权的轮转法。