进程之进程控制块与虚拟地址空间
1.进程概念
在用户层面,进程是一次程序的动态运行实例,
在操作系统层面,进程是操作系统进行资源调度和分配的基本单位,每一个进程都有自己独立的地址空间和运行状态。
操作系统为进程创建了一系列的数据结构来管理进程。操作系统会为每个进程创建一个虚拟地址空间和进程控制块。
2.虚拟地址空间
在32位操作系统下,一个进程最多可以拥有4G的内存空间,在早期的计算机系统中,将程序直接加载到内存,也就是说,
程序所访问到的地址空间就是真实的内存空间,当有多个进程同时执行时,先将一个进程全部加载内存,然后,在剩下的内存
中取空间分配给其他进程。
这样的分配方式存在很大问题,首先地址空间不隔离,使得A进程完全可能修改B进程的数据,同时,内存的利用率极低。
这时引入了虚拟地址空间的概念,为每一个进程创建一个虚拟的地址空间,在32位系统下,虚拟空间的大小为4G,然后使用
页表机制将虚拟地址映射到实际物理地址
虚拟地址实现了多进程之间的地址空间隔离,任何一个进程不会干扰到其他进程的运行,同时,地址空间的映射由操作系统
完成,提高了空间利用率。
linux下,地址空间分为5段,地址空间从高到低为
1.内核区:内核空间为操作系统内核保留,不允许应用程序对内核空间进行读写
2.栈区:栈向下生长,保存局部变量,函数参数,返回地址等
3.内存映射段:
4.堆区:堆向上生长,保存动态开辟的空间
5.BSS段:未初始化或者初始化为0的全局变量和局部静态变量
6.数据段:已初始化且初始化为非0的全局变量和局部静态变量
7.代码段:可执行代码,字符串字面值,只读变量
8.保留区:位于虚拟空间最底层,未赋予物理地址,对它的引用是违法操作,此处收到操作系统保护而用户无权访问,这也是为什
么C语言将空指针设置为0,地址0在保留区,一般不会指向有效数据。
3.task_struct
linux操作系统使用task_struct管理进程,换句话说,在内核层面,它看不到各种应用程序,各种运行中的进程,它看到的是一个个
task_struct。一个进程对应一个task_struct,操作系统使用链式结构将一个个task_struct管理起来。task_struct中的数据成员标识了
进程的所有信息。
1.进程状态
volatile long state; int exit_state;
state的取值标识了进程的当前状态,包括运行,阻塞,僵死等等。
2.进程pid
pid_t pid;
pid_t tgid;
进程pid标识进程编号
3.进程内核栈
void *stack;
4.标记
unsigned int flags;
5.标识进程亲属关系的成员
struct task_struct *real_parent; /* real parent process */ struct task_struct *parent; /* recipient of SIGCHLD, wait4() reports */ 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 */
6.performance Event
#ifdef CONFIG_PERF_EVENTS struct perf_event_context *perf_event_ctxp[perf_nr_task_contexts]; struct mutex perf_event_mutex; struct list_head perf_event_list; #endif
分析进程的性能问题
7.进程调度
int prio, static_prio, normal_prio; unsigned int rt_priority; const struct sched_class *sched_class; struct sched_entity se; struct sched_rt_entity rt; unsigned int policy; cpumask_t cpus_allowed;
4.进程状态
进程的基本状态为以下三种
1.就绪状态:进程已经获得除过cpu之外的所有资源,只要获得cpu,就可以立即执行,通常处于就绪状态的进程被存放在
就绪队列中
2.执行状态:进程获得cpu,程序在执行状态
3.阻塞状态:进程因为某些事件暂时无法继续执行时,便放弃处理机而处于暂停状态。
在linux系统中,进程的具体状态为;
R :运行状态:就绪态和执行状态
S :可中断睡眠状态,进程处于等待状态,当进程需要的资源被释放时,进程转为运行态。
D :不可中断睡眠状态:进程处于等待状态,只能用wake_up()函数唤醒
Z:退出状态,进程已经终止,但父进程还未回收进程的资源。