进程的概念
程序是存储在磁盘中的静态文件,本身不具备运行能力。只有当程序被加载至内存、交由CPU执行后,才会转化为可运行的动态实体,这个动态运行的实体就是进程(Process),简单来说,进程的本质就是程序的一次执行过程。
进程的标识
同一个程序支持多次启动、重复执行,每一次独立的运行都会生成一个全新的进程。为了有序管理系统中并行运行的多个进程,杜绝进程混乱、权限冲突等问题,操作系统会为每个进程分配专属的身份与管理信息,核心标识要素主要分为进程ID、用户ID两类。
进程ID(Process ID,PID)
进程ID是操作系统为每一个进程分配的唯一数字标识符,相当于进程在系统中的专属身份编号。该标识具备全程恒定的特性,在进程从创建、运行、暂停到最终销毁的完整生命周期内,始终保持唯一、固定不变。
操作系统依靠PID精准区分每一个独立进程,以此完成进程启停控制、硬件资源分配、运行优先级调度、进程状态监控等一系列核心操作,是操作系统识别、管理进程的基础核心标识。
用户ID(User ID,UID)
在Windows、Linux、macOS等多用户操作系统中,系统会为每个登录用户分配专属的用户ID,而所有运行中的进程都会绑定对应的UID,核心作用是标识进程的所属用户。
UID的核心价值是实现系统的权限管控。操作系统会根据进程绑定的用户身份,限制进程对系统资源的访问权限,比如普通用户启动的进程无法修改系统核心文件、无法访问其他用户的私有文件,管理员用户的进程则拥有更高的资源操作权限,以此保障系统资源的安全性和隔离性。
进程的核心组成结构
除了上述用于身份识别、权限控制的标识信息外,每个进程自身包含三大核心组成结构,分别是程序段、数据段和进程控制块(PCB),其中程序段和数据段是进程的内存结构组成部分,而进程控制块则是操作系统管理进程的核心数据结构。
进程控制块(Process Control Block,PCB)
程序加载至内存、正式执行前,操作系统会优先为其创建专属的数据结构,用于全程管理进程,该数据结构就是进程控制块(PCB),它是操作系统管理进程的核心数据结构,是记录进程全部核心运行信息的“信息档案”。系统每创建一个进程,就会同步生成一个对应的PCB,全程跟踪、记录进程的运行状态,是操作系统高效调度多进程的核心依据。
PCB中包含的关键信息极为全面,我们以Linux内核的源码为例(能拿到源码的就只有Linux了,哈哈哈哈)其位于内核源码的include/linux/sched.h文件中,核心结构体定义如下:
1 | struct task_struct { |
这个task_struct结构体就是PCB的核心体现,包含了进程的状态、内核栈指针、引用计数、标志位、调试状态等关键信息,当然,远远不止这些信息,这个结构体的定义在源码里整整写了1600多行。Linux操作系统会读取和修改该结构体中的数据,以实现对进程的创建、调度、终止等操作,当进程被销毁时,PCB也会被释放,确保系统资源的高效利用。
程序段
有了进程控制块,操作系统就可以管理进程的运行状态了,但进程本身还需要有实际的代码和数据来执行任务,于是,操作系统会把程序的指令也读到内存当中,用于存放指令的内存区域就叫做程序段(Text Segment),也叫代码段,这个程序的执行过程其实就是CPU不断地从程序段中取指令来执行的过程。
数据段
除了程序段之外,进程还需要一个内存区域来存放它在运行过程中需要使用的数据,这个内存区域就叫做数据段(Data Segment),数据段中存放着进程运行时需要使用的全局变量、静态变量等数据,程序在执行过程中会不断地访问和修改数据段中的内容。
进程的特征
相比于程序的静态特征,进程具有以下几个动态特征:
- 动态性:进程是程序的一次执行过程,具有动态的生命周期,从创建、运行、暂停到销毁,整个过程充满了变化和不确定性。
- 独立性:每个进程都是系统中的一个独立实体,拥有自己的内存空间、系统资源和执行状态,进程之间相互独立,互不干扰。
- 并发性:操作系统支持多个进程同时运行,进程之间可以并发执行,操作系统通过调度算法来管理多个进程的执行顺序和资源分配,实现多任务处理。
- 异步性:进程的执行是异步的,进程之间没有固定的执行顺序,操作系统会根据进程的优先级、资源需求等因素来调度进程的执行,进程之间的执行顺序可能会发生变化。
- 结构性:进程具有明确的结构组成,包括程序段、数据段和进程控制。