进程是一个正在执行的程序,在linux中每一个进程都有由一个task_struct结构体来定义,也就是我们平时所说的PCB,这个结构体包含了一个进程所需要的所有信息。
它包含了关于进程的以下信息:
进程状态:
volatile long state;
#define TASK_RUNNING 0 //进程正在执行或准备执行
#define TASK_INTERRUPTIBLE 1 //进程因为某些条件处于阻塞,一旦等待的条件成立,进程进入就绪态度
#define TASK_UNINTERRUPTIBLE 2 //也是阻塞态,但是无法被信号唤醒,只有它所等待的资源可用的时候,才会唤醒
#define TASK_STOPPED 4 //进程被停止运行
#define TASK_TRACED 8 //进程被debugger等进程监视
#define EXIT_DEAD 16 //进程被杀死,进程的最终状态
#define EXIT_ZOMBIE 32 //进程的僵尸状态
进程标识符
pid_t pid; //进程的标识符
pid_t tgid; //线程组标识符 是希望同一线程组线程具有相同的tgid
进程标记符
unsigned int flags; //反应进程的状态信息,用于内核识别当前的进程状态
我们认识一些常见的进程标记
PF_FORKNOEXEC //进程刚被创建,但还没被执行
PF_SUPERPRIV //进程拥有超级用户权限
PF_SIGNALED //进程被信号杀死
PF_EXITING //表示进程开始关闭
表示进程亲属关系的成员
struct task_struct __rcu *real_parent; /* real parent process */
struct task_struct __rcu *parent; /* recipient of SIGCHLD, wait4() reports */
truct 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 //当前操作系统执行进程的父进程,如果父进程不存在,则指向init(1号)进程
parent //指向当前进程的父进程,当当前进程终止时,需要向它发送wait4()的信号
children //位于链表的头部,链表的所有元素都是chidren的子进程
group_leader //指向进程组的领头进程
ptrace系统调用
Ptrace提供了一种父进程,它可以被用来控制子进程的运行,常被用来进行断点调试,当它被设置为0时表示不需要追踪。
进程调度优先级
int prio, static_prio, normal_prio;
unsigned int rt_priority;
prio //动态优先级
static_prio //静态优先级 100-139
normal_prio //它的值取决于静态优先级和调度策略
rt_priority //用来保存实时优先级 0-99
实时优先级和静态优先级的取值范围中,值越高优先级越低
进程地址空间
进程都拥有自己的资源,这些资源指的就是进程的地址空间。
struct mm_struct *mm, //进程所拥有的内存空间描述符,对于内核线程的mm为NULL
*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
操作系统对进程的控制依赖于进程控制块,操作系统在创建进程时也会自动创建进程控制块,进程切换,进程创建和终止都和进程块有关。