操作系统知识总结——进程

1 进程的概念

进程是程序的一次执行过程,是一个动态的概念,是操作系统进行资源分配和调度的基本单位
每个进程都有自己的地址空间,一般包含文本区域、数据区域和堆栈。

2 进程的状态

在这里插入图片描述
一个进程有五种基本状态:运行态、就绪态、阻塞态、运行态、退出态。

  • 新建态:刚刚创建的进程,操作系统还尚未将它加入到可执行进程组,通常是进程控制块(PCB)已经创建但是尚未加载到内存中的新进程。
  • 就绪态:进程已经持有除CPU资源以外的所需资源,正等待被分配CPU资源。进程调度的方法有多种,例如基于时间片的调度算法、响应比优先调度算法、最短作业调度算法、先来先服务调度算法等。
  • 运行态:进程已经获取CPU资源,正在被运行
  • 阻塞态:进程正在等待某种条件,在条件满足前无法获取到CPU资源。例如等待IO操作完成、一个进程等待另外一个进程的输入。
  • 退出态:操作系统从可执行组中释放出的进程,意味着进程已经停止或被取消。

3 进程控制块

操作系统在管理和控制进程时,需要知道进程的位置以及属性。
通常一个进程的属性集称之为进程控制块(PCB),进程的程序、数据、栈和属性集称为进程映像

进程控制块信息分为三类:进程标识信息、进程状态信息、进程控制信息。

3.1 进程标识信息

一般包含进程ID、父进程ID、用户标识符。

3.2 进程状态信息

又称CPU状态信息,一般包含用户可见寄存器、控制和状态寄存器、栈指针。

  • 用户可见寄存器是CPU在用户模式下执行机器代码时可以访问的寄存器。
  • 栈指针:每个进程都有一个或多个系统栈,栈用于保存参数和过程调用或系统调用地址,栈指针指向栈顶。
  • 控制和状态寄存器用于控制操作系统的各种处理器寄存器,包括:
    • 程序计数器:下一条
    • 条件码:最近算术或逻辑运算结果
    • 状态信息:包括中断允许/禁用标志、执行模式
3.3 进程控制信息

进程控制信息一般包含调度和状态信息,数据结构,进程间通信、进程特权、存储管理、资源所有权和使用情况。

  • 调度和状态信息
    操作系统执行调度时所需的信息。包含:

    • 进程状态:例如运行态、阻塞态、停止态等
    • 优先级:描述进程调度的优先级
    • 调度相关信息,具体内容取决于进程调度算法,例如进程上次进入就绪状态的时间。
    • 事件:进程在继续执行前等待的事件标识。
  • 数据结构:进程可以以一种数据结构链接到其他进程。

  • 进程间通信:各种标记、信号和信息可与两个无关进程间的通信关联。

  • 进程特权:进程持有的特权信息,例如可访问的内存或者可以执行的指令类型。

  • 存储管理:包括指向描述分配给该进程的虚存的段表或者页表的指针。

  • 资源所有权和使用情况,指示进程控制的资源,比如打开一个文件。还可包含处理器或其他资源的使用历史。

4 进程的创建

4.1 进程创建的原因

进程创建的原因有:

  • 新的批处理作业
    磁盘中的批处理作业控制流会提供给操作系统,当操作系统准备接收新的作业时,就会读取下一个作业控制命令
  • 交互登录
    终端用户登录到系统
  • 为提供服务而由操作系统创建
    操作系统可以主动创建一个进程,代表用户程序执行一个功能。
  • 通过现有的进程派生
    用户程序可以通过系统调用创建出子进程。
4.2 进程创建的步骤
  1. 为进程分配一个唯一的进程ID
  2. 为进程分配内存空间
  3. 初始化进程控制块
  4. 设置正确的链接
  5. 创建或扩充其它数据结构

UNIX中的进程创建是基于内核调用fork函数实现的,当一个进程发出fork请求时,该进程会被切换到内核态,并完成以下操作:

  1. 在进程表中为新的进程分配一个空项
  2. 为子进程分配一个唯一进程标识符
  3. 复制父进程的进程映像,共享内存除外
  4. 增加父进程所拥有文件的计数器
  5. 将子进程更新为就绪态
  6. 将子进程的ID号返回给父进程,将0值返回给子进程

5 进程上下文切换

进程切换是指操作系统中断一个正在运行的进程,将另一个进程置于运行模式,并把控制权交给后者。

5.1 进程切换的时机

在发生中断、陷阱或者执行系统调用的时候,就会将进程的控制权转移给操作系统。

对于中断,控制权首先转移给中断处理器,中断处理器完成一些基本的工作后,再将控制权转移给已发生的特定中断相关的操作系统例程,具体案例有:

  • 时钟中断:在基于时间片的进程调度算法下,如果进程的运行时间已经超出了最大允许的时间,就将进程切换到就绪状态,保存进程上下文后切换到另外一个进程。
  • IO中断
  • 内存失效:当进程试图访问一个不在物理内存中的虚拟地址时,操作系统必须从硬盘将这一个内存块调入物理内存,在调入期间,进程会进入阻塞状态直到调入完成。

对于陷阱,操作系统会确定错误或者异常条件是否致命,如果致命(例如尝试访问非法地址)那么会将进程置于退出态,并切换进程,不致命时,操作系统的动作取决于操作系统的设计,可能会尝试恢复程序或者切换进程等。

对于系统调用,当进程执行了IO操作指令(例如打开文件)时,就会切换到内核态,并将用户进程设置为阻塞态,然后切换到其它进程。

5.2 执行切换的步骤

进程切换不同于进程的用户态和内核态切换(简称模式切换),模式切换无需改变运行态进程的状态,开销相对较小。进程的切换开销较大,具体步骤如下:

  1. 保存处理器的上下文,包括程序计数器和其它寄存器
  2. 更新当前处于运行态进程的PCB,包括更改进程的状态标志位和其它信息
  3. 把该进程的PCB转移到相应的队列
  4. 根据进程调度算法,选择一个就绪的进程
  5. 更新所选进程的PCB
  6. 更新内存管理数据结构。

6 用户态和内核态

为了防止进程破坏操作系统,按照进程的特权级别,将其划分为了用户态和内核态。

  • 内核态:CPU可以访问内存的所有数据,包括外围设备,例如硬盘,网卡,CPU也可以将自己从一个程序切换到另一个程序。
  • 用户态:只能受限的访问内存,且不允许访问外围设备,占用CPU的能力被剥夺,CPU资源可以被其他程序获取。

用户态和内核态的切换称之为模式切换

6.1 模式切换的场景

在发生以下情况时,进程会从内核态切换到用户态:

  • 系统调用:当应用程序需要借助操作系统提供的服务时,就需要切换到内核态。例如调用fork函数生成子进程,或者调用printf向标准输出写入数据。
  • 异常:当CPU在执行运行在用户态下的程序时,发生了某些事先不可知的异常,当前进程就会切换到处理此异常的内核相关程序中。例如尝试访问一个非法的地址。
  • 外围设备的中断:当外围设备(例如磁盘)完成用户的请求后,会向CPU发出中断信号,此时CPU会暂时停止执行下一个指令,转而去响应中断信号,并调用中断程序,此时也就自然从用户态切换到了内核态。
6.2 Linux系统中的系统调用

在Linux系统中,系统调用能够切换到内核态是基于中断信号实现的。过程如下:

  1. 系统调用编号装入eax寄存器
  2. 调用int $0x80指令,产生一个中断号为0x80的中断。
  3. 此时CPU切换到内核态处理该中断信号,找到中断描述符表中的第0x80项,它指向了一个系统调用处理程序system_call()
  4. 内核中保存了一张系统调用表 ,该表中保存了系统调用编号和其对应的服务例程,此时从寄存器eax取出系统调用号,然后就可以找出相应的服务例程了。
    在这里插入图片描述

文章根据现有操作系统书籍和网上资源总结而成,如有错误欢迎指正!

发布了117 篇原创文章 · 获赞 96 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/abc123lzf/article/details/104469974