Linux-进程初识之task-struct-PCB

认识进程

进程定义

1.是程序的一个执行实例
2.是正在执行的程序

通俗的讲进程就是程序被加载到内存中,
等待CPU处理时或正在被CPU处理的程序就被叫做进程。

由此我们可以知道,程序和进程的区别:

1.程序是静止的,存在于硬盘上,也就是外设上,而进程是动态的,进程存在与内存中
2.进程是动态的,进程存在与内存中。
3.进程是有生命周期和生命状态的

进程描述

程序被加载到内存中,操作系统会为它分配一块空间,用于存储程序中的数据信息,为了更好地描述和管理这些信息,操作系统用一个结构体来描述进程,管理进程。我们把这个结构体叫做PCB。

当有很多进程被加载到内存,被结构结构体描述,形成多个PCB,为了维护秩序,避免混乱,操作系统又将这些PCB组织起来,形成一个链表,Linux系统下用双链表来组织PCB,这些PCB形成的链表在Linux环境下又叫task-struct-PCB。每个进程都把它的信息放在task-struct-PCB中,让cpu去处理这些信息。操作系统管理进程,实际上是管理PCB里的数据信息。下面我们来查看task-struct-PCB里面都含有那些信息并尝试去理解其含义。

关于task-struct-PCB结构体

1 进程状态

volatile long state;/* -1 unrunnable, 0 runnable, >0 stopped */

这个是进程的运行时状态,-1代表不可运行,0代表可运行,>0代表已停止。
volatile关键字是降低编译器对代码的优化,是state变量一直从变量的内存中读取内容而不是寄存器;从而保证对操作系统状态实时访问的稳定性。
state状态有如下取值(源码):

/* 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

/* Convenience macros for the sake of set_current_state: */
#define TASK_KILLABLE           (TASK_WAKEKILL | TASK_UNINTERRUPTIBLE)
#define TASK_STOPPED            (TASK_WAKEKILL | __TASK_STOPPED)
#define TASK_TRACED         (TASK_WAKEKILL | __TASK_TRACED)

#define TASK_IDLE           (TASK_UNINTERRUPTIBLE | TASK_NOLOAD)

/* Convenience macros for the sake of wake_up(): */
#define TASK_NORMAL         (TASK_INTERRUPTIBLE | TASK_UNINTERRUPTIBLE)
#define TASK_ALL            (TASK_NORMAL | __TASK_STOPPED | __TASK_TRACED)

/* get_task_state(): */
#define TASK_REPORT         (TASK_RUNNING | TASK_INTERRUPTIBLE | \
                     TASK_UNINTERRUPTIBLE | __TASK_STOPPED | \
                     __TASK_TRACED | EXIT_DEAD | EXIT_ZOMBIE | \
                     TASK_PARKED)

介绍几种常用进程状态信息:

状态简称作用
TASK_RUNNINGR表示进程要么正在执行,要么正要准备执行
TASK_INTERRUPTIBLES进程因为等待某些条件处于阻塞(挂起的状态),一旦等待的条件成立,进程便会从该状态转化成就绪状态,俗称浅度睡眠,可被唤醒,可中断,可被杀死
TASK_UNINTERRUPTIBLEDTASK_INTERRUPTIBLE类似,但是我们传递任意信号等不能唤醒他们,只有它所等待的资源可用的时候,他才会被唤醒。俗称深度睡眠,不可被杀死,唤醒,中断,除非自己醒来
TASK_STOPPEDT进程被停止执行,不做任何事情
EXIT_DEADX表示进程的最终状态。
EXIT_ZOMBIEZ进程的执行被终止,但是其父进程还没有使用wait()等系统调用来获知它的终止信息,此时进程成为僵尸进程

下文我将重点介绍僵尸进程。

2.标示符:描述进程的”唯一标示符”,用来区别别的进程

pid_t pid;     //进程的标识符
pid_t tgid;    //线程组标识符

3*表示进程亲属关系的成员**

/*
 * 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 */
struct list_head sibling;       /* linkage in my parent's children list */
struct task_struct *group_leader;       /* threadgroup leader */
状态解释
real_parent指向其父进程,如果创建它的父进程不再存在,则指向PID为1的init进程
Pparent指向当前进程的父进程,当它终止时,必须向它的父进程发送信号。它的值通常与real_parent相同
children链表的头部,链表中的所有元素都是它的子进程
sibling把当前进程插入到兄弟链表中
group_leader指向其进程组的领头进程
real_parent指向其父进程,如果创建它的父进程不再存在,则指向PID为1的init进程

4.trace系统调用

Ptrace提供了一种父进程,它可以被用来控制子进程的运行,常被用来进行断点调试,当它被设置为0时表示不需要追踪。

5.优先级

int prio, static_prio, normal_prio;
unsigned int rt_priority;

相对于其他进程的优先级
例如:如果有好几个进程都在执行,那就会涉及到那个进程先执行那个进程后执行,这就会和进程的优先级有关

备注:

优先级与权限区别:

权限:能和不能去操作
优先级:权限已经拥有,谁先执行的问题   

6.进程地址空间

进程都拥有自己的资源,这些资源指的就是进程的地址空间,每个进程都有着自己的地址空间,在task_struct中,有关进程地址空间的定义如下:

truct mm_struct *mm, *active_mm;
/* per-thread vma caching */
u32 vmacache_seqnum;
struct vm_area_struct *vmacache[VMACACHE_SIZE];
#if defined(SPLIT_RSS_COUNTING)
struct task_rss_stat    rss_stat;
#endif

/*  http://lxr.free-electrons.com/source/include/linux/sched.h?V=4.5#L1484  */
#ifdef CONFIG_COMPAT_BRK
unsigned brk_randomized:1;
#endif
成员描述
mm进程所拥有的内存空间描述符,对于内核线程的mm为NULL
active_mm指进程运行时所使用的进程描述符
zebra stripes被用来记录缓冲信息

7 .内存指针:包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针

.8. 上下文数据:进程执行时处理器的寄存器中的数据

9. I/O状态信息:包括显示的I/O请求,分配给进程的I/O设备和被进程使用的文件列表

10 .记账信息:可能包括处理器时间总和,使用的时钟数总和,时间限制,记账号等

11. 其他信息
关于task-struct-PCB详细信息可以查看
https://elixir.bootlin.com/linux/latest/source/include/linux/sched.h
本文仅按照目前学习截取了相关信息,会不定期更新。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值