1.进程控制块的思维导图
2.task_struct结构
查看Linux的task_struct(即PCB)结构,我搜集到了以下各行代码的含义:
struct thread_info thread_info; //存放的是PCB中频繁访问和需要快速访问的字`段。内核依赖于该字段来获得当前进程的PCB
volatile long state; //进程状态(-1就绪态,0运行态,>0停止态)
void *stack; //stack用来维护分配给进程的内核栈。
int lock_depth; //锁的深度
unsigned char fpu_counter; //FPU使用计数
pid_t pid; //进程pid
pid_t tgid; //在线程组内,每个线程都使用此线程组内第一个线程pid并将此值存入tgid
unsigned int flags; //用来反映一个进程的状态信息,但不是运行状态,用于内核识别进程当前的状态
struct task_struct *real_parent; //指向父进程的指针,如果父进程不存在了,则指向PID为1的进程
struct task_struct *parent; //指向父进程的,值与real——parent相同,需要向它的父进程发送信号
struct list_head children; //表示链表的头部,链表中的所有元素都是它的子进程
struct list_head sibling; //用于当前进程插入兄弟链表当中
struct task_struct *group_leader; //指向进程组的领头进程
unsigned int ptrace; //ptrace系统调用,关于实现断点调试,跟踪进程运行。ptrace是一种提供父进程控制子进程运行,并且可以检查和改变它的核心image。当ptrace设置为0时不需要被跟踪。
int prio, static_prio, normal_prio; //prio用来保存动态优先级,static_prio用来保存静态优先级,可以通过nice系统进行修改,normal_prio用来保存静态优先级和调度策略
unsigned int rt_priority; //prio用来保存动态优先级
unsigned int policy; //表示调度策略
const struct sched_class *sched_class;//表示调度类
struct sched_entity se; //表示普通进程的一个调用的实体,每一个进程都有其中之一的实体
struct sched_rt_entity rt; //表示实时进程的调用实体,每个进程都有其中之一的实体
struct mm_struct *mm, *active_mm; //mm 进程所拥有的用户空间的内存描述符。active_mm 指向进程运行时使用的内存描述符,对于普通的进程来说,mm和active_mm是一样的,但是内核线程是没有进程地址空间的,所以内核线程的mm是空的,所以需要初始化内核线程的active_mm。
int exit_state; //表示进程终止的状态
int exit_code, exit_signal; //exit_code用来设置进程的终止代号,exit_signal 设置为-1的时候表示是某个线程组当中的一员,只有当线程组的最后一个成员终止时,才会产生型号给父进程
int pdeath_signal; //用来判断父进程终止时的信号
cputime_t utime, stime,
utimescaled, stimescaled; //utime/stime 用于记录进程在用户状态/内核态下所经过的定时器。utimescaled/stimescaled 分别记录进程在用户态和内核态的运行的时间
cputime_t gtime; //记录虚拟机的运行时间
cputime_t prev_utime, prev_stime; //prev_utime/prev_stime 记录当前的运行时间
unsigned long nvcsw, nivcsw; //nvcsw/nicsw 是自愿/非自愿上下文切换计数
struct timespec start_time; //进程创建时间
struct timespec real_start_time; //进程创建时间,real还包括了进程睡眠时间
struct task_cputime cputime_expires; //cputime_expires 用来统计进程或进程组被跟踪的处理器时间,三个成员对应的是下面的cpu_times[3]的三个链表
struct list_head cpu_timers[3];
struct signal_struct *signal; //指向进程信号描述符
struct sighand_struct *sighand; //指向进程信号处理程序描述符
sigset_t blocked, real_blocked; //blocked 表示被阻塞信号的掩码
struct sigpending pending; //存放私有挂起信号的数据结构
unsigned long sas_ss_sp; //信号处理程序备用堆栈的地址
struct fs_struct *fs; //进程可执行镜像所在的文件系统
struct files_struct *files; //进程当前打开的文件
补充:
(1)flags可使用的值为:
可使用的标记 | 功能 |
---|---|
PF_FORKNOEXEC | 进程刚创建,但还没执行。 |
PF_SUPERPRIV | 超级用户特权。 |
PF_DUMPCORE | 关于核心。 |
PF_SIGNALED | 进程被信号(signal)杀出。 |
PF_EXITING | 进程开始关闭。 |
(2)policy表示进程的调度策略,主要有以下五种:
种类 | 功能 |
---|---|
SCHED_NORMAL | 用于普通进程 |
SCHED_BATCH | 普通进程策略的分化版本,采用分时策略 |
SCHED_IDLE | 优先级最低,系统空闲时才跑这类进程 |
SCHED_FIFO | 先入先出的调度算法 |
SCHED_RR | 实时调度算法,采用时间片,相同优先级的任务当用完时间片就会放到队列的尾部,保证公平性,同时,高优先级的任务抢占低优先级的任务。 |
SCHED_DEADLINE | 新支持的实时调度策略,正对突发性计算 |
(3)调度类
调度类 | 功能 |
---|---|
idle_sched_class | 每一个cpu的第一个pid=0的线程,是一个静态的线程 |
stop_sched_class | 优先级最高的线程,会中断所有其他的线程,而且不会被其他任务打断 |
rt_sched_slass | 作用在实时线程 |
fair_sched_class | 作用的一般线程 |
它们的优先级顺序为Stop>rt>fair>idle
(4)进程的定时器,一共是三种定时器。
定时器类型 | 解释 | 更新时刻 |
---|---|---|
ITIMER_REAL | 实时定时器 | 实时更新,不在乎进程是否运行 |
ITIMER_VIRTUAL | 虚拟定时器 | 只在进程运行用户态时更新 |
ITIMER_PROF | 概况定时器 | 进程运行于用户态和系统态进行更新 |