概述
前面的文章我们已经了解了操作系统的启动流程和用户态调用操作系统的接口的原理,这篇我们来研究一下操作系统对于多个程序是如何管理的。只做每个概念的初步了解,具体深入的研究在后面的篇幅中展开
程序和进程
假设我们写了两个程序
- 程序1
MOV AX,1
MOV BX,1
ADD AX,BX
...
- 程序2
MOV AX,10
MOV BX,10
ADD AX,BX
...
假设我们让cpu执行完52行指令的时候切换到200行再执行一会,等执行到202行的时候再切回来继续执行,效果如图
那么这时候cpu切回来程序的时候, ax和bx是多少呢?如果只修改ip寄存器为200让cpu去执行指令,那么切回来的时候ax,bx就会变成20,10而不是2,1。所以cpu切换到其他程序执行的时候,需要保存当前程序执行的某些信息
我们把这个要保存的信息成为PCB
从上面的例子我们可以看出,在磁盘中静态的程序和在内存中动态的程序是不同的,动态的程序CPU需要有一个PCB来维护当前的状态,我们把这个动态的程序称之为进程。
多进程的组织
我们知道了操作系统为了管理多个进程的切换,给每个进程都分配了一个PCB的数据结构来管理进程。
从上图我们可以看到进程分为几个不同的状态
操作系统管理好进程的状态就是操作系统的多进程图片原理。
多进程如何交替
我们上面知道了操作系统是如何组织多个进程,通过给进程标记状态来管理进程。接下来我们来看看操作系统是如何让CPU在多个进程之间切换。
一个进程启动了磁盘读写
pCur.state = W' // 标记当前PCB为阻塞态
addDiskWaitQueue(pCur) // 把当前进程放入阻塞队列中
schedule(); // 进行切换
schedule()
{
pNew = getNext(ReadyQueue) // 从就绪队列中获得一个新的pcb
switch_to(pCur,pNew); // 把cpu的现场保护起来,然后把新的PCB放入cpu中
}
多进程的内存管理
我们再来看两个程序
因为多个进程是存放在同一个内存当中的,如果我一个进程不小心修改了另外一个进程在内存中的数据,就会造成危害。那么操作系统是如何来避免这种情况的发生的呢?
每个进程都被分配了一个内存映射表,不同进程编写代码的时候访问同一块内存最后都会被映射到不同的真实物理内存上从而实现了多个进程的共存。