认识进程
进程定义:
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_RUNNING | R | 表示进程要么正在执行,要么正要准备执行 |
TASK_INTERRUPTIBLE | S | 进程因为等待某些条件处于阻塞(挂起的状态),一旦等待的条件成立,进程便会从该状态转化成就绪状态,俗称浅度睡眠,可被唤醒,可中断,可被杀死 |
TASK_UNINTERRUPTIBLE | D | TASK_INTERRUPTIBLE类似,但是我们传递任意信号等不能唤醒他们,只有它所等待的资源可用的时候,他才会被唤醒。俗称深度睡眠,不可被杀死,唤醒,中断,除非自己醒来 |
TASK_STOPPED | T | 进程被停止执行,不做任何事情 |
EXIT_DEAD | X | 表示进程的最终状态。 |
EXIT_ZOMBIE | Z | 进程的执行被终止,但是其父进程还没有使用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
本文仅按照目前学习截取了相关信息,会不定期更新。