Linux下的进程控制块(PCB)
本⽂转载⾃
1. 导语
进程在操作系统中都有⼀个户⼝,⽤于表⽰这个进程。这个户⼝操作系统被称为PCB(进程控制块),在linux中具体实现是 task_struct数据结构。
2. 说明
进程控制块(PCB)(系统为了管理进程设置的⼀个专门的数据结构,⽤它来记录进程的外部特征,描述进程的运动变化过程。系统利⽤PCB来控和管理进程,所以PCB是系统感知进程存在的唯⼀标志。进程与PCB是⼀⼀对应的)在不同的操作系统中对进程的控制和管理机制不同,PCB中的信息多少不⼀样,通常PCB应包含如下⼀些信息。
1、进程:每个进程都必须有⼀个唯⼀的标识符,可以是字符串,也可以是⼀个数字。
2、进程当前状态 status:说明进程当前所处的状态。为了管理的⽅便,时会将相同的状态的进程组成⼀个队列,如就绪进程队列,等待进程则要根据等待的事件组成多个,如等待打印机队列、等待磁盘完成队列等等。
3、进程相应的程序和数据地址,以便把PCB与其程序和数据联系起来。
4、进程。列出所拥有的除CPU外的,如拥有的,打开的⽂件列表等。
5、 priority:进程的优先级反映进程的紧迫程度,通常由⽤户指定和系统设置。
6、现场保护区 cpustatus:当进程因某种原因不能继续占⽤CPU时(如等待打印机),释放CPU,这时就要将CPU的各种状态信息保护起来,为将来再次得到处理机恢复CPU的各种状态,继续运⾏。
7、进程同步与通信机制⽤于实现进程间互斥、同步和通信所需的信号量等。
8、进程所在队列PCB的链接字根据进程所处的现⾏状态,进程相的PCB参加到不同队列中。PCB链接字指出该进程所在队列中下⼀个进程PCB的⾸地址。
9、与进程有关的其他信息。如进程记账信息,进程占⽤CPU的时间等。
在linux 中每⼀个进程都由task_struct 来定义. task_struct就是我们通常所说的PCB。
3. 源码
struct task_struct
{
volatile long state; //说明了该进程是否可以执⾏,还是可中断等信息
unsigned long flags; // flags 是进程号,在调⽤fork()时给出
int sigpending; // 进程上是否有待处理的信号
mm_segment_t addr_limit; //进程地址空间,区分内核进程与普通进程在内存存放的位置不同 //0-0xBFFFFFFF for user-thead //0-0xFFFFFFFF for kernel-thread //调度标志,表⽰该进程是否需要重新调度,若⾮0,则当从内核态返回到⽤户态,会发⽣调度
volatile long need_resched;
int lock_depth; //锁深度
long nice; //进程的基本时间⽚
//进程的调度策略,有三种,实时进程:SCHED_FIFO,SCHED_RR, 分时进程:SCHED_OTHER
unsigned long policy;
struct mm_struct *mm; //进程内存管理信息
int processor;
//若进程不在任何CPU上运⾏, cpus_runnable 的值是0,否则是1 这个值在运⾏队列被锁时更新
unsigned long cpus_runnable, cpus_allowed;
struct list_head run_list; //指向运⾏队列的指针
unsigned long sleep_time; //进程的睡眠时间
//⽤于将系统中所有的进程连成⼀个双向循环链表, 其根是init_task
struct task_struct *next_task, *prev_task;
struct mm_struct *active_mm;
struct list_head local_pages; //指向本地页⾯
unsigned int allocation_order, nr_local_pages;
struct linux_binfmt *binfmt; //进程所运⾏的可执⾏⽂件的格式
int exit_code, exit_signal;
int pdeath_signal; //⽗进程终⽌时向⼦进程发送的信号
unsigned long personality;
//Linux可以运⾏由其他UNIX操作系统⽣成的符合iBCS2标准的程序
int did_exec:1;
pid_t pid; //进程标识符,⽤来代表⼀个进程
pid_t pgrp; //进程组标识,表⽰进程所属的进程组
pid_t tty_old_pgrp; //进程控制终端所在的组标识
pid_t session; //进程的会话标识
pid_t tgid;
int leader; //表⽰进程是否为会话主管
struct task_struct *p_opptr,*p_pptr,*p_cptr,*p_ysptr,*p_osptr;
struct list_head thread_group; //线程链表
struct task_struct *pidhash_next; //⽤于将进程链⼊HASH表
struct task_struct **pidhash_pprev;
wait_queue_head_t wait_chldexit; //供wait4()使⽤
struct completion *vfork_done; //供vfork() 使⽤
unsigned long rt_priority; //实时优先级,⽤它计算实时进程调度时的weight值
//it_real_value,it_real_incr⽤于REAL定时器,单位为jiffies, 系统根据it_real_value
//设置定时器的第⼀个终⽌时间. 在定时器到期时,向进程发送SIGALRM信号,同时根据
//it_real_incr重置终⽌时间,it_prof_value,it_prof_incr⽤于Profile定时器,单位为jiffies。
/
/当进程运⾏时,不管在何种状态下,每个tick都使it_prof_value值减⼀,当减到0时,向进程发送
//信号SIGPROF,并根据it_prof_incr重置时间.
//it_virt_value,it_virt_value⽤于Virtual定时器,单位为jiffies。当进程运⾏时,不管在何种
//状态下,每个tick都使it_virt_value值减⼀当减到0时,向进程发送信号SIGVTALRM,根据
//it_virt_incr重置初值。
unsigned long it_real_value, it_prof_value, it_virt_value;
unsigned long it_real_incr, it_prof_incr, it_virt_value;
struct timer_list real_timer; //指向实时定时器的指针
struct tms times; //记录进程消耗的时间
unsigned long start_time; //进程创建的时间
//记录进程在每个CPU上所消耗的⽤户态时间和核⼼态时间
long per_cpu_utime[NR_CPUS], per_cpu_stime[NR_CPUS];
//内存缺页和交换信息:
//min_flt, maj_flt累计进程的次缺页数(Copy on Write页和匿名页)和主缺页数(从映射⽂件或交换
//设备读⼊的页⾯数); nswap记录进程累计换出的页⾯数,即写到交换设备上的页⾯数。
//cmin_flt, cmaj_flt, cnswap记录本进程为祖先的所有⼦孙进程的累计次缺页数,主缺页数和换出页⾯数。 //在⽗进程回收终⽌的⼦进程时,⽗进程会将⼦进程的这些信息累计到⾃⼰结构的这些域中
unsigned long min_flt, maj_flt, nswap, cmin_flt, cmaj_flt, cnswap;
int swappable:1; //表⽰进程的虚拟地址空间是否允许换出
//进程认证信息
//uid,gid为运⾏该进程的⽤户的⽤户标识符和组标识符,通常是进程创建者的uid,gid
//euid,egid为有效uid,gid
//fsuid,fsgid为⽂件系统uid,gid,这两个ID号通常与有效uid,gid相等,在检查对于⽂件
//系统的访问权限时使⽤他们。
//suid,sgid为备份uid,gid
uid_t uid,euid,suid,fsuid;
gid_t gid,egid,sgid,fsgid;
int ngroups; //记录进程在多少个⽤户组中
gid_t groups[NGROUPS]; //记录进程所在的组
//进程的权能,分别是有效位集合,继承位集合,允许位集合
kernel_cap_t cap_effective, cap_inheritable, cap_permitted;
int keep_capabilities:1;
struct user_struct *user;
struct rlimit rlim[RLIM_NLIMITS]; //与进程相关的资源限制信息
unsigned short used_math; //是否使⽤FPU
char comm[16]; //进程正在运⾏的可执⾏⽂件名
int link_count, total_link_ count; //⽂件系统信息
//NULL if no tty 进程所在的控制终端,如果不需要控制终端,则该指针为空
struct tty_struct *tty;
unsigned int locks;
//进程间通信信息
struct sem_undo *semundo; //进程在信号灯上的所有undo操作
struct sem_queue *semsleeping; //当进程因为信号灯操作⽽挂起时,他在该队列中记录等待的操作
//进程的CPU状态,切换时,要保存到停⽌进程的task_struct中
struct thread_struct thread;
struct fs_struct *fs; //⽂件系统信息
struct files_struct *files; //打开⽂件信息
spinlock_t sigmask_lock; //信号处理函数
struct signal_struct *sig; //信号处理函数
sigset_t blocked; //进程当前要阻塞的信号,每个信号对应⼀位 struct sigpending pending; //进程上是否有待处理的信号
unsigned long sas_ss_sp;
size_t sas_ss_size;
int (*notifier)(void *priv);
void *notifier_data;
sigset_t *notifier_mask;
u32 parent_exec_id;
linux下的sleep函数u32 self_exec_id;
spinlock_t alloc_lock;
void *journal_info;
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论