进程是一个具有一定独立功能的 程序 在一个 数据集合 上的 一次动态执行 过程(进程 = 程序 + 数据 + 动态执行)。一个进程包含了程序代码、相关数据以及进程控制块等信息。程序代码定义了进程要执行的操作,数据则是程序在运行过程中使用的变量、数据结构等。动态执行指的是进程在计算机系统中被调度并执行的过程。

本文是进程与线程的第一部分,主要介绍进程的静态部分,包括进程的定义、组成、特点和进程控制结构等。

进程描述

进程的定义

进程(process)是一个具有一定独立功能的 程序 在一个 数据集合 上的 一次动态执行 过程。

保存在磁盘中的静态程序代码文件,通过编译、链接转换成可执行文件,然后被加载到内存中执行,称为一个进程,进行实际的执行操作。

进程的组成

一个进程包括

  • 程序的代码;
  • 程序处理的数据;
  • 程序计数器中的值:用于指示下一条将要运行的指令;
  • 一组通用的寄存器的当前值:用于存储临时数据和中间结果,包括通用寄存器、状态寄存器等。
  • 堆和栈:堆用于动态分配内存,存储动态创建的对象和数据结构;栈用于存储函数调用和局部变量等。
  • 一组系统资源(如打开的文件、网络连接)

总之,进程包含了正在运行的一个程序的所有状态信息。

进程和程序的联系

  • 程序是产生进程的基础;
  • 程序的每次运行构成不同的进程;
  • 进程是程序功能的体现;
  • 通过多次执行,一个程序可以对应多个进程;通过调用关系,一个进程可以包括多个程序。

进程和程序的区别

  • 进程是动态的、程序是静态的。
    • 程序是有序代码的集合,进程是程序的执行,进程有核心态(如打开文件是通过系统调用,由操作系统在内核态处理的)、用户态。
  • 进程是暂时的、程序是永久的。
    • 进程是一个状态变化的过程,程序可以长久保存。
  • 进程和程序的组成不同:进程的组成包括程序、数据和进程控制块(进程状态信息)。

进程的特点

  • 动态性:可动态地创建和结束进程;
  • 并发性:进程可以被独立调度并占用 CPU 运行;
    • 并发:多个进程在一段时间内交替执行。
    • 并行:在某一时刻,多个进程在同时执行(并行仅在多核设备上才支持)。
  • 独立性:不同进程的工作不相互影响;
    • 内存管理中的页表是保障措施之一(每个进程都有自己的页表,不会访问到对方的页表的地址空间)。
  • 制约性:因访问共享数据或资源,或进程间同步而产生制约。
    • 这可能会导致资源竞争或数据不一致等问题,因此需要采取相应的措施来解决制约问题,如使用互斥锁、信号量等机制来进行进程间的同步与通信。

老师抛出了一个问题:如果你要设计一个 OS, 怎么样来实现其中的进程管理机制?

进程控制块(PCB)

PCB 概述

计算机中有那么多进程,那这些进程是如何被操作系统管理起来的呢

进程控制块 (Process Control Block, PCB):操作系统中用于管理和维护进程的 数据结构

每个进程在操作系统中都有一个对应的 PCB,它包含了进程的各种属性和状态信息。换句话说,操作系统用 PCB 来描述进程的基本情况以及运行变化的过程。PCB 是进程存在的唯一标志。

使用 PCB

  • 进程的创建:为该进程生成一个 PCB;
  • 进程的终止:回收它的 PCB;
  • 进程的组织管理:通过对 PCB 的组织管理来实现。

PCB 三大类信息

  1. 进程标志信息:包括进程标志(Process ID)、产生者标志(Parent Process ID)和用户标志(User ID)。这些信息用于唯一标识进程、记录父进程和标识进程所属的用户。

  2. CPU 状态信息保存区:保存了进程的运行现场信息,包括用户可见寄存器(用于用户程序的数据、地址等寄存器)、控制和状态寄存器(如程序计数器 PC、程序状态字 PSW)以及栈指针(用于过程调用、系统调用、中断处理和返回时的栈操作)。

  3. 进程控制信息:包括调度和状态信息(用于操作系统调度和占用 CPU 资源)、进程间通信信息(用于支持进程间通信的标志、信号、信件等)、存储管理信息(包含指向进程映像存储空间的数据结构)、进程所用资源(说明进程打开、使用的系统资源,如打开的文件等)以及有关数据结构的链接信息(用于连接到进程队列或其他相关进程的 PCB)。

PCB 的组织方式

多个进程的 PCB 是如何被操作系统有效地管理的呢

链表:同一状态 的进程其 PCB 构成 一个 链表,多个状态 对应 多个不同 的链表。

  • 各状态的进程形成不同的链表:就绪链表、阻塞链表。

索引表:同一状态 的进程归入一个 index 表(由 index 指向 PCB),多个状态 对应 多个不同 index 表。

  • 各状态的进程形成不同的索引表:就绪索引表、阻塞索引表。

PCB 扩展内容

以下内容由 GPT 生成,不保证内容的 100% 准确。

PCB 通常包含以下重要的信息:

  1. 进程标识符(Process ID):唯一标识该进程的数字或字符串。

  2. 程序计数器(Program Counter):存储当前执行指令的地址,用于指示下一条要执行的指令。

  3. 寄存器集合:保存进程执行过程中的寄存器内容,包括通用寄存器、程序状态字、堆栈指针等。

  4. 进程状态(Process State):表示进程当前所处的状态,常见的状态有就绪(Ready)、运行(Running)、阻塞(Blocked)等。

  5. 进程优先级(Process Priority):用于确定进程的调度顺序,通常由进程调度算法根据一定的策略进行设置。

  6. 资源指针(Resource Pointers):指向进程所拥有的资源的指针,如打开文件列表、内存分配信息等。

  7. 父进程指针(Parent Process Pointer):指向该进程的父进程。

  8. 子进程指针(Child Process Pointer):指向该进程的子进程。

  9. 进程控制信息(Process Control Information):存储了进程的创建时间、运行时间、等待时间等统计信息。

PCB 在操作系统中起到了重要的作用,它记录了进程的基本信息,并且通过操作系统的调度算法,可以根据 PCB 中的信息对进程进行管理和调度。当进程状态发生变化时,PCB 中的相应字段也会随之更新,以便操作系统能够及时响应和处理进程的状态变化。

以下是一个用 C 语言表示 PCB 的数据结构的示例(操作系统实际 PCB 设计可能有所不同):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
struct ProcessControlBlock {
int processID;
int programCounter;
struct RegisterSet {
// 寄存器集合,包括通用寄存器、程序状态字、堆栈指针等
// ...
} registers;
enum ProcessState {
READY,
RUNNING,
BLOCKED
} state;
int priority;
void *resourcePointers;
struct ProcessControlBlock *parentProcess;
struct ProcessControlBlock *childProcess;
struct ProcessControlInformation {
// 进程的统计信息,如创建时间、运行时间、等待时间等
// ...
} controlInfo;
};

上述的数据结构中,ProcessControlBlock表示进程控制块,包含了进程的各种属性和状态信息。其中,registers表示寄存器集合,state表示进程状态,priority表示进程优先级,resourcePointers表示资源指针,parentProcesschildProcess 分别表示父进程和子进程的指针,controlInfo表示进程的控制信息。

参考资料:

  1. https://github.com/OXygenMoon/OperatingSystemInDepth
  2. https://blog.csdn.net/weixin_53407527/article/details/125027431