进程管理—进程描述符(task_struct)

前言


当把一个程序加载到内存当中,此时,这个时候就有了进程,关于进程,有一个相关的叫做进程控制块(PCB),这个是系统为了方便进行管理进程所设置的一个数据结构,通过PCB,就可以记录进程的特征以及一些信息。
内核当中使用进程描述符task_struct。
这个task_struct就是一个定义的一个结构体,通过这个结构体,可以对进程的所有的相关的信息进行维护,对进程进行管理。

接下来我们需要对task_struct结构体当中的成员进行一些分析。

linux内核版本
Linux version 2.6.32-431.el6.i686

1 task_struct


1.1 进程状态


volatile long state;
int exit_state;`

表示进程的状态,
在进程执行的时候,它会有一个状态,这个状态对于进程来说是很重要的一个属性。进程主要有以下几个状态。

state可能的取值
这里写图片描述

这里写图片描述
这些状态就不再一一说明了,后续进程篇会有专门的说明。

1.2 进程标识符(PID)


pid_t pid;
pid_t tgid;

每个进程都有进程标识符、用户标识符、组标识符,进程标识符对于每一个进程来说都是唯一的。内核通过进程标识符来对不同的进程进行识别,一般来说,行创建的进程都是在前一个进程的基础上PID加上1作为本进程的PID。为了linux平台兼容性,PID一般最大为32767。

1.3 进程内核栈


void *stack

stack用来维护分配给进程的内核栈,内核栈的意义在于,进程task_struct所占的内存是由内核动态分配的,确切的说就是内核根本不给task_struct分配内存,只给内核栈分配8KB内存,并且一部分会提供给task_struct使用。
task_struct结构体大约占用的大小为1K左右,根据内核版本的不同,大小也会有差异。
所以,也就可以知道内核栈最大也就是7KB,否则,内核栈会覆盖task_struct结构。

1.4 标记


unsigned int flags

用来反映一个进程的状态信息,但不是运行状态,用于内核识别进程当前的状态,flags的取值如下:

可使用的标记 功能
PF_FORKNOEXEC 进程刚创建,但还没执行。
PF_SUPERPRIV 超级用户特权。
PF_DUMPCORE 关于核心。
PF_SIGNALED 进程被信号(signal)杀出。
PF_EXITING 进程开始关闭。

1.5 表示进程亲属关系的成员


struct task_struct *real_parent;
struct task_struct *parent;
struct list_head children;
struct list_head sibling;
struct task_struct *group_leader;

linux系统当中,考虑到进程的派生,所以进程之间会存在父进程和子进程这样的关系,当然,对于同一个父进程派生出来的进程,他们的关系当然是兄弟进程了。

成员 功能
real_parent 指向父进程的指针,如果父进程不存在了,则指向PID为1的进程
parent 指向父进程的,值与real——parent相同,需要向它的父进程发送信号
children 表示链表的头部,链表中的所有元素都是它的子进程
sibling 用于当前进程插入兄弟链表当中
group_leader 指向进程组的领头进程

1.6 ptrace系统调用


unsigned int ptrace;
struct list_head ptraced;
struct list_head ptrace_entry;

首先我们要清楚ptrace是什么东西,ptrace是一种提供父进程控制子进程运行,并且可以检查和改变它的核心image。当trace设置为0时不需要被跟踪。

1.7 性能诊断工具——Performance Event


#ifdef CONFIG_PERF_EVENTS
#ifndef __GENKSYMS__
    void * __reserved_perf__;
#else
    struct perf_event_context *perf_event_ctxp;
#endif
    struct mutex perf_event_mutex;
    struct list_head perf_event_list;
#endif

Performance Event是性能诊断工具,这些成员用来帮助它进行分析进程性能问题。

1.8 进程调度


    int prio, static_prio, normal_prio;
    unsigned int rt_priority;
成员 功能
static_prio 保存静态优先级,可以通过nice系统进行修改
rt_priority 保存实时优先级
normal_prio 保存静态优先级和调度策略
prio 保存动态优先级

调度进程利用这部分信息决定系统当中的那个进程最应该运行,并且结合进程的状态信息保证系统运作高效。

提到进程调度,当然还需要说明一下进程调度策略,我们来看下关于调度策略的成员:

    unsigned int policy;
    const struct sched_class *sched_class;
    struct sched_entity se;
    struct sched_rt_entity rt;
成员 功能
policy 调度策略
sched_class 调度类
se 普通进程的一个调用的实体,每一个进程都有其中之一的实体
rt 实时进程的调用实体,每个进程都有其中之一的实体
cpus_allowed 用于控制进程可以在处理器的哪里运行

policy表示进程的调度策略,主要有以下五种:

种类 功能
SCHED_NORMAL 用于普通进程
SCHED_BATCH 普通进程策略的分化版本,采用分时策略
SCHED_IDLE 优先级最低,系统空闲时才跑这类进程
SCHED_FIFO 先入先出的调度算法
SCHED_RR 实时调度算法,采用时间片,相同优先级的任务当用完时间片就会放到队列的尾部,保证公平性,同时,高优先级的任务抢占低优先级的任务。
SCHED_DEADLINE 新支持的实时调度策略,正对突发性计算

说完了调度策略,我们再来看一下调度类。

调度类 功能
idle_sched_class 每一个cpu的第一个pid=0的线程,是一个静态的线程
stop_sched_class 优先级最高的线程,会中断所有其他的线程,而且不会被其他任务打断
rt_sched_slass 作用在实时线程
fair_sched_class 作用的一般线程

它们的优先级顺序为Stop>rt>fair>idle

1.9进程的地址空间


    struct mm_struct *mm, *active_mm;
成员 功能
mm 进程所拥有的用户空间的内存描述符
  • 6
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值