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

2019-07-14 08:37发布

认识进程

进程定义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
本文仅按照目前学习截取了相关信息,会不定期更新。