进程是程序执行,以及内存空间,以及执行上下文等一系列要素

线程是一个进程中的多个小的执行单元,其共享进程的堆和方法栈的资源,可以并发,每个线程有自己的程序计数器

线程崩溃则整个进程崩溃,因为线程不是独立的,但是各个进程之间是完全独立的,所以多进程比多线程健壮

线程切换只是CPU的直接访问切换,但是进程切换是包括分配内存空间,保存和产生执行上下文等步骤的切换,所以线程切换比进程开销更小

虚存:通过进程的分页设计,来让进程的一部分在运行进程的时候可以从外存实时加载到内存,以减少内存的开销

虚存

先介绍几个定义:

  1. 段:有代码段和数据段,每个段在内存中占用连续的物理空间
  2. CS寄存器:存储代码段的段基址,或者存放段选择子
  3. DS寄存器:存储数据段的段基址,或者存放段选择子
  4. IP寄存器:存储代码段的段偏移量
  5. 全局段描述符表:存储在内存中,有各个(可执行文件)代码和数据段的基址
  6. 全局段描述符表寄存器:存储全局段描述符表在内存中的基址

CPU访问内存中代码段和数据段的方式有以下几种:

直接存取

要执行可执行文件时,代码段和数据段被分配唯一的物理地址,但缺点在不能同时执行多次这个程序,而且地址锁定也不灵活

段基址+段偏移量

为了灵活访问内存中的不同地方的代码,出现了段基址+段偏移量的方法,典型的是Intel的8086,如图:

CS寄存器,DS寄存器存放代码段和数据段的段基址,IP寄存器存放段偏移量,访问的时候CPU获取段基址和段偏移量(CS:IP方法)来进行定位

后续要获取有关段地址的信息时,可以直接从段寄存器里面获取,加快效率

段选择子+段偏移量

设置了全局段描述符表,来存放各个段的信息(包括位置基址)
段选择子是对某个特定段用于定位其在全局段描述符表中的位置,所以定位方式为:
先将段选择自防砸段寄存器中(如S寄存器),CPU再从段寄存器中获取段选择子的13位高位来确定在全局段描述符表中的位置,再从全局段描述符表寄存器中获取全局段描述符表的基址,计算得段的实际地址,在加上IP寄存器中的偏移量,进行访问

虚拟地址

虚拟地址是一个进程在执行的时候所分配给的逻辑地址,它并不是在物理地址(内存),而是一个进程所需要空间的虚拟编号,其实际对应的部分可能在物理内存中,也可能在磁盘中

为了充分利用物理内存,采用分页系统,将物理内存以4K为一个单位分成若干页,并且每一页编有物理页号,对应的,虚拟内存也以相同大小编成了若干虚拟页,有:
物理内存 = 物理页号(PPN) + 物理页偏移量(PPO)
虚拟内存 = 虚拟页号(VPN) + 虚拟页偏移量(VPO)

虚拟页相当于一张为了进程而设计的执行表,是针对进程全面的,要执行进程的时候,需要为了进程而访问的哪一块存储的的时候,找找虚拟页,如果已经要访问的存储在内存中那就再好不过了,如果不在的话,那要不就是在磁盘中,我们就把他放到内存里,要不就是压根没分配存储空间,那我们就给它在磁盘上分配一个再放到内存里

虚拟页和物理页有一定的映射关系,其映射方法通过硬件MMU实现,虚拟页三种映射状态如下:

  1. 未分配,指虚拟页没有分配磁盘空间
  2. 未缓冲:指虚拟页没有分配到物理内存,而是在映射在磁盘的状态
  3. 已缓冲:指虚拟页已经有了物理内存的映射

有几个虚拟页的映射是所有进程一致的:
内核共享库

为了判断和管理虚拟页的映射状态,在内存中会有一个页表(PT)
页表有两列:有效位和地址,有效位的0和1和地址列是否为null可以组合判断虚拟页是三种状态的哪一个

页表专门有一个页表基址寄存器(PTBR)

以下介绍虚拟地址翻译物理地址的方法:

有两种结果,命中或者未命中,命中就是虚拟页已缓冲,未命中就是未缓冲或者未分配

命中:

  1. CPU将虚拟地址(VA)送入MMU,MMU根据页表基址寄存器中页表的起始地址加上虚拟页号,找到了页表项的物理地址PTEA。

  2. MMU将PTEA送入到高速缓冲或者内存。

  3. 从高速缓冲或者内存中找到页表项(PTE),返回页表项(PTE)给MMU。

  4. MMU根据PTE找出物理页号,然后加上虚拟页偏移量形成物理地址(PA),送入到高速缓冲或者内存。

  5. 高速缓冲或者内存获取数据,返回数据给处理器。

未命中:

  1. CPU将虚拟地址(VA)送入MMU,MMU根据页表基址寄存器中页表的起始地址加上虚拟页号,找到了页表项的物理地址PTEA。

  2. MMU将PTEA送入到高速缓冲或者内存。

  3. 从高速缓冲或者内存中找到页表项(PTE),返回页表项(PTE)给MMU。

  4. MMU根据PTE,发现页不在内存中,未命中,因此MMU发送一个缺页中断,交由缺页异常处理程序处理。

  5. 缺页异常处理程序根据页置换算法,选择出一个牺牲页,如果这个页面已经被修改了,则写出到磁盘上,最后将这个牺牲页的页表项有效位设置为0,存入磁盘地址。

  6. 缺页异常程序处理程序调入新的页面,如果该虚拟页尚未分配磁盘空间,则分配磁盘空间,然后磁盘空间的页数据拷贝到空闲的物理页上,并更新PTE的有效位为1,更新物理页号,缺页异常处理程序返回后,再回到发生缺页中断的指令处,重新按照页表项命中的步骤执行

以下介绍虚拟地址翻译物理地址的方法:

有两种结果,命中或者未命中,命中就是虚拟页已缓冲,未命中就是未缓冲或者未分配

命中:

  1. CPU将虚拟地址(VA)送入MMU,MMU根据页表基址寄存器中页表的起始地址加上虚拟页号,找到了页表项的物理地址PTEA。

  2. MMU将PTEA送入到高速缓冲或者内存。

  3. 从高速缓冲或者内存中找到页表项(PTE),返回页表项(PTE)给MMU。

  4. MMU根据PTE找出物理页号,然后加上虚拟页偏移量形成物理地址(PA),送入到高速缓冲或者内存。

  5. 高速缓冲或者内存获取数据,返回数据给处理器。

未命中:

  1. CPU将虚拟地址(VA)送入MMU,MMU根据页表基址寄存器中页表的起始地址加上虚拟页号,找到了页表项的物理地址PTEA。

  2. MMU将PTEA送入到高速缓冲或者内存。

  3. 从高速缓冲或者内存中找到页表项(PTE),返回页表项(PTE)给MMU。

  4. MMU根据PTE,发现页不在内存中,未命中,因此MMU发送一个缺页中断,交由缺页异常处理程序处理。

  5. 缺页异常处理程序根据页置换算法,选择出一个牺牲页,如果这个页面已经被修改了,则写出到磁盘上,最后将这个牺牲页的页表项有效位设置为0,存入磁盘地址。

  6. 缺页异常程序处理程序调入新的页面,如果该虚拟页尚未分配磁盘空间,则分配磁盘空间,然后磁盘空间的页数据拷贝到空闲的物理页上,并更新PTE的有效位为1,更新物理页号,缺页异常处理程序返回后,再回到发生缺页中断的指令处,重新按照页表项命中的步骤执行