程序:完成特定任务的一系列指令集合
代码段+数据段
-----放在磁盘中的程序
进程:进行就是正在进行中的程序
1、用户角度: 进程是程序的一次动态执行过程
2、操作系统: 进程是操作系统分配资源的基本单位,也是最小单位
很抽象的概念,那么,到底什么是进程呢?又为什么要有进程?
CPU一次只能处理一个程序,CPU速度很快,而内存很慢,所以CPU会有大量的时间都是空闲的。而CPU又是很昂贵的,为了解决浪费CPU的情况,就出现了中断处理,将程序分成一小片一小片的,这个进程执行一点,那个进程执行一点。虽然在内部进程的执行是一段一段的,但是CPU的速度很快的(速度都是纳秒级别的),所以我们是感受不到进程执行过程中的停顿的。
CPU执行程序的过程
既然是一段一段执行,CPU在执行一个进程时,其他的进程就处于等待状态,为什么执行当前的这个进程而不是其他进程呢?这就要分情况讨论了,有可能是因为轮到它们的时间片用完了,也可能是它在等待某种资源等,所以在内存中,每个进程的状态可能是不同的,那么,进程的状态有哪些呢?
再分详细一点的话就有七态了
现在的系统都是多道程序处理系统,那就代表着在同一段时间内,系统里边执行的程序可能有很多个,那么,系统通过什么去区分他们呢?
进程的标识号:
系统为每一个进程分配一个唯一的标识号(正整数),这个标识号就称为进程ID(progress identifer),即PID。最早的时候有一个0号进程,是写死在内核里边的,所以操作系统在启用的时候,0号进程就启用了。
0号进程的作用:启动1号进程,将1号进程启动了之后就没事干了
1号进程是系统启动的第一个用户态进程,其他进程就相当于1号进程的子孙。
所以之后我们创建的进程的最小为2号。
想象一下一个小区里边,每套房都有一个门牌号(相当于我们的PID),为什么仅凭一个房间号就能确认哪个是你自己的家,而不会走到你邻居家呢?因为每一个门牌号都有属于自己的空间,所以每个进程也应该要有属于自己的地址空间。这个空间给多大呢?4G,Linux下有3G在用户空间,1G在内核。Windows下,有2G在内核,2G在用户空间。每个进程都有4G,同一时间内可能会有成百上千乃至上万个进程,累加起来,所需的内存是非常庞大的,然而我们的计算机内存并没有那么多的内存(内存可是很贵的),所以,进程的地址空间其实是虚拟地址,是操作系统给它们画的一个大饼。
前边已经说了,进程是一小片一小片的执行的,所以,即使进程认为自己拥有4G空间,但是并不会在同一时刻使用4G空间,那么,操作系统只需要在你需要使用的时候给你分配一点空间就行了。你不用的时候,操作系统就可以将这块空间给别的进程使用。那怎么通过虚拟地址找到对应的物理地址(在内存中真时存在的地址)呢?操作系统为每个进程提供了一个MMU(内存管理单元),里边有一张表,里边将虚拟内存映射到物理内存的情况记录着,然后每个进程里边都有一个指针(在mm_struct 里边的pgd指针)指向这张表
除了以上讲的进程pid地指空间,进程在执行过程中,可能会打开文件等资源,还有进程在切换的时候,当前的状态和它执行到哪了(上下文信息)这些信息是不是都应该记录下来呢?那这些信息都存放在哪呢?
接下来要提出一个进程中最重要的概念,PCB(process control block)即,进程控制块。既然是控制进程的,进程的相关信息都应该存放在里边。那么PCB到底是何方神圣呢?其实PCB的本质就是一个名为task_struct 的结构体。里边存放着进程几乎所有的信息。
task_struct(PCB)内容分类:
标识符:就是进程的PID。
状态:任务状态、退出代码,退出信号等。
优先级:相对于其他进程的优先级。
程序计数器:程序中即将被执行的下一条指令的地址。
内存指针:包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针。
上下文数据:进程执行时处理器的寄存器中的数据。
I/O状态信息:包括显示的I/O请求,分配给进程的I/O设备和被进程使用的文件列表。
记账信息:可能包括处理器时间总和,使用的时钟数总和,时间限制,记账号等。
PCB可以说是很强大的了,那么,操作系统想要控制一个进程,只需控制其PCB就行了。所以操作系统控制一个进程分两步:
1、通过PCB将一个进程描述起来
2、将这些PCB组织起来。
怎么将这些PCB组织起来呢?前边已经说了,PCB是一个结构体,那么创建一个链表,每个节点都存放一个PCB,来一个进程,就把他的PCB挂到链表上,来一个挂一个,那么,操作系统只要拎着这个链表的头,后边所有的PCB都可以获取到了,PCB获取到了,整个进程的控制权也就拿到了。
进程有不同的状态,如果不同状态的进程都放在一个链表上的话,如果进程很多,链表就会很长,这就降低了操作系统调度在对进程进行调度时的查找效率。为了解决这个问题,操作系统创建了索引表。让同一状态的进程归入一个索引表再由索引指向PCB,多个状态对应多个不同的索引表,各状态的进程形成不同的索引表,就绪索引表、阻塞索引表……