来谈谈Linux中的task_struct结构体

在介绍task_struct,我们要先来看几个概念

一:进程的概念

      1. 从用户角度来看:进程是程序的一次动态执行过程

      2.从内核角度看:

                              

  3.那PCB结构中的数据有哪些呢

                                             

4.在进程执行的任意时刻,都可由如下元素来表征

  • 标识符:与进程相关的唯一标识符,用来区别正在执行的进程和其他进程
  • 状态:描述进程的状态,因为进程有挂起,阻塞,运行等好几个状态,所以都有个标识符来记录进程的执行状态
  • 优先级:如果有好几个进程正在执行,就涉及到进程被执行的先后顺序的问题,这和进程优先级这个标识符有关。
  • 程序计数器:程序中即将被执行的下一条指令的地址
  • 内存指针:程序代码和进程相关数据的指针。
  • 上下文数据:进程执行时处理器的寄存器中的数据
  • I / O状态信息:包括显示的I / O请求,分配给进程的I / O设备和被进程使用的文件列表等
  • 记账信息:包括处理器的时间总和,记账号等等   

5.进程标识符


6.进程创建的一般过程


二:进程模型

1.两状态模型

在任何时刻,一个进程要么正在执行,要么未执行,因而可以构建最简单的模型


2.五状态模型

(1)运行态:进程正在执行。

(2)就绪态:进程做好了准备,只要有机会就开始执行。

(3)阻塞态:进程在某些事情发生前不能执行

(4)新建态:刚刚创建的进程

(5)退出态:操作系统从可执行进程组中释放出的进程


3.经典Linux七态


三.task_struct的源码成员解析

task_struct头文件sched.h链接https://elixir.bootlin.com/linux/latest/source/include/linux/sched.h

(1)进程状态

/* -1 unrunnable, 0 runnable, >0 stopped: */

volatile longstate;

上面这个变量就是描述进程状态的成员,结合Ç语言我们学到的知识挥发性关键字是降低编译器对代码的优化,是状态变量一直从变量的内存中读取内容而不是寄存器;从而保证对操作系统状态实时访问的稳定性。

(2)成员的可能取值如下

/*
 * Task state bitmask. NOTE! These bits are also
 * encoded in fs/proc/array.c: get_task_state().
 *
 * We have two separate sets of flags: task->state
 * is about runnability, while task->exit_state are
 * about the task exiting. Confusing, but this way
 * modifying one set can't modify the other one by
 * mistake.
 */

/* Used in tsk->state: */
#define TASK_RUNNING			0x0000
#define TASK_INTERRUPTIBLE		0x0001
#define TASK_UNINTERRUPTIBLE		0x0002
#define __TASK_STOPPED			0x0004
#define __TASK_TRACED			0x0008
/* Used in tsk->exit_state: */
#define EXIT_DEAD			0x0010
#define EXIT_ZOMBIE			0x0020
#define EXIT_TRACE			(EXIT_ZOMBIE | EXIT_DEAD)
/* Used in tsk->state again: */
#define TASK_PARKED			0x0040
#define TASK_DEAD			0x0080
#define TASK_WAKEKILL			0x0100
#define TASK_WAKING			0x0200
#define TASK_NOLOAD			0x0400
#define TASK_NEW			0x0800
#define TASK_STATE_MAX			0x1000
我们可以看到变量定义后面的注释,它说明变量内容<0是不运行的,=0是运行状态,>0是停止状态。

(3)

状态描述
TASK_RUNNING表示进程正在执行或者处于准备执行的状态
TASK_INTERRUPTIBLE进程因为等待某些条件处于阻塞(挂起的状态),一旦等待的条件成立,进程便会从该状态转化成就绪状态
TASK_UNINTERRUPTIBLE意思与TASK_INTERRUPTIBLE类似,但是我们传递任意信号等不能唤醒他们,只有它所等待的资源可用的时候,他才会被唤醒。
TASK_STOPPED进程被停止执行
TASK_TRACED进程被debugger等进程所监视。
EXIT_ZOMBIE进程的执行被终止,但是其父进程还没有使用wait()等系统调用来获知它的终止信息,此时进程成为僵尸进程
EXIT_DEAD进程被杀死,即进程的最终状态。
TASK_KILLABLE当进程处于这种可以终止的新睡眠状态中,它的运行原理类似于 TASK_UNINTERRUPTIBLE,只不过可以响应致命信号
(4)进程标识符

pid_t pid;//进程的标识符

pid_t tgid;//线程组标识符//进程标识符就不用解释了,它的引入是为了区别每个进程;

tgid的引入是由于Unix程序员希望同一组线程具有相同的pid所以就引入了tgid.

(5)进程标记符

    unsignedint flags; /* per process flags, defined below */

flags反应进程的状态信息,用于内核识别当前进程的状态。

取值范围如下:

/*
 * Per process flags
 */
#define PF_IDLE			0x00000002	/* I am an IDLE thread */
#define PF_EXITING		0x00000004	/* Getting shut down */
#define PF_EXITPIDONE		0x00000008	/* PI exit done on shut down */
#define PF_VCPU			0x00000010	/* I'm a virtual CPU */
#define PF_WQ_WORKER		0x00000020	/* I'm a workqueue worker */
#define PF_FORKNOEXEC		0x00000040	/* Forked but didn't exec */
#define PF_MCE_PROCESS		0x00000080      /* Process policy on mce errors */
#define PF_SUPERPRIV		0x00000100	/* Used super-user privileges */
#define PF_DUMPCORE		0x00000200	/* Dumped core */
#define PF_SIGNALED		0x00000400	/* Killed by a signal */
#define PF_MEMALLOC		0x00000800	/* Allocating memory */
#define PF_NPROC_EXCEEDED	0x00001000	/* set_user() noticed that RLIMIT_NPROC was exceeded */
#define PF_USED_MATH		0x00002000	/* If unset the fpu must be initialized before use */
#define PF_USED_ASYNC		0x00004000	/* Used async_schedule*(), used by module init */
#define PF_NOFREEZE		0x00008000	/* This thread should not be frozen */
#define PF_FROZEN		0x00010000	/* Frozen for system suspend */
#define PF_KSWAPD		0x00020000	/* I am kswapd */
#define PF_MEMALLOC_NOFS	0x00040000	/* All allocation requests will inherit GFP_NOFS */
#define PF_MEMALLOC_NOIO	0x00080000	/* All allocation requests will inherit GFP_NOIO */
#define PF_LESS_THROTTLE	0x00100000	/* Throttle me less: I clean memory */
#define PF_KTHREAD		0x00200000	/* I am a kernel thread */
#define PF_RANDOMIZE		0x00400000	/* Randomize virtual address space */
#define PF_SWAPWRITE		0x00800000	/* Allowed to write to swap */
#define PF_NO_SETAFFINITY	0x04000000	/* Userland is not allowed to meddle with cpus_allowed */
#define PF_MCE_EARLY		0x08000000      /* Early kill for mce process policy */
#define PF_MUTEX_TESTER		0x20000000	/* Thread belongs to the rt mutex tester */
#define PF_FREEZER_SKIP		0x40000000	/* Freezer should not count it as freezable */
#define PF_SUSPEND_TASK		0x80000000      /* This thread called freeze_processes() and should not be frozen */
常用状态
状态描述
PF_FORKNOEXEC表示进程刚被创建,但还没有执行
PF_SUPERPRIV表示进程拥有超级用户特权
PF_SIGNALED表示进程被信号杀出
PF_EXITING表示进程开始关闭

(6)表示进程亲属关系的成员

/*
* pointers to (original) parent process, youngest child, younger sibling,
* older sibling, respectively. (p->father can be replaced with
* p->real_parent->pid)
*/
struct task_struct __rcu *real_parent; /* real parent process */
struct task_struct __rcu *parent; /* recipient of SIGCHLD, wait4() reports */
/*
* children/sibling forms the list of my natural children
*/
struct list_head children; /* list of my children */
成员描述
real_parent指向当前操作系统执行进程的父进程,如果父进程不存在,指向pid为1的init进程
paren指向当前进程的父进程,当当前进程终止时,需要向它发送wait4()的信号
children位于链表的头部,链表的所有元素都是children的子进程
group_leader指向进程组的领头进程
(7)ptrace系统调用
Ptrace提供了一种父进程,它可以被用来控制子进程的运行,常被用来进行断点调试,当它被设置为0时表示不需要追踪。
(8)进程调度
优先级
int prio, static_prio, normal_prio;
unsigned int rt_priority;
成员描述
static_prio用来保存静态优先级,可以调用nice系统直接来修改取值范围为100~139
rt_priority用来保存实时优先级,取值范围为0~99
prio用来保存动态优先级
normal_prio它的值取决于静态优先级和调度策略
实时优先级和静态优先级的取值范围中,值越大,优先级越高

(9)进程地址空间


成员描述
mm进程所拥有的内存空间描述符,对于内核线程的mm为NULL
active_mm指进程运行时所使用的进程描述符
rss_stat被用来记录缓冲信息

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值