二、进程与线程

(一)进程与线程

1.进程的概念和特征

(1) 进程的概念

多道程序环境下,程序并发执行会失去封闭性,出现间断性和不可再现性,因此引入进程来描述和控制并发执行,实现操作系统的并发性与共享性。

进程实体(进程映像):由程序段相关数据段进程控制块(PCB) 三部分构成。

  • PCB:是进程存在的唯一标志,用于描述进程的基本情况和运行状态,控制和管理进程。
  • 创建 / 撤销进程的本质:创建 / 撤销进程实体中的 PCB。

进程的定义

  1. 程序的一次执行过程。
  2. 程序及其数据在处理机上顺序执行时所发生的活动。
  3. 具有独立功能的程序在一个数据集合上运行的过程,是系统进行资源分配和调度的独立单位。
  4. 传统操作系统定义:进程是进程实体的运行过程,是系统进行资源分配和调度的独立单位。
(2) 进程的特征

进程与程序是截然不同的概念,其基本特征如下:

  1. 动态性:进程是程序的一次执行,有创建、活动、暂停、终止等生命周期,是动态产生、变化和消亡的,这是进程最基本的特征。
  2. 并发性:多个进程可同存于内存,在一段时间内同时运行,这是进程和操作系统的重要特征。
  3. 独立性:进程是能独立运行、独立获得资源和独立接受调度的基本单位,未建立 PCB 的程序不能作为独立单位参与运行。
  4. 异步性:进程按各自独立、不可预知的速度向前推进,异步性会导致执行结果不可再现,因此操作系统需配置相应的进程同步机制。

2.进程的状态与转换

进程的 5 种状态
  1. 运行态:进程在处理机上执行。单处理机中任一时刻只有 1 个进程处于运行态。
  2. 就绪态:进程已获得除处理机外的所有所需资源,只要获得处理机即可立即运行。多个就绪进程会排成就绪队列
  3. 阻塞态(等待态):进程因等待某一事件(如 I/O 完成、等待资源)而暂停运行,即使处理机空闲也无法执行。多个阻塞进程会根据阻塞原因排成不同的阻塞队列
  4. 创建态:进程正在被创建,尚未转到就绪态。步骤为:申请空白 PCB → 填写控制信息 → 分配资源 → 转入就绪队列(若资源不足则保持创建态)。
  5. 终止态:进程从系统中消失,可能是正常结束或因其他原因退出。系统会先将进程置为终止态,再处理资源回收和 PCB 释放等工作。
3 种基本状态间的转换:
  1. 就绪态 → 运行态:处于就绪态的进程被调度程序选中,获得处理机时间片,开始执行。
  2. 运行态 → 就绪态:进程的时间片用完,或有更高优先级进程进入就绪队列,调度程序将当前进程转为就绪态,让更高优先级进程执行。
  3. 运行态 → 阻塞态:进程请求某一资源(如外设、系统调用)或等待某一事件(如 I/O 完成),主动放弃处理机,转为阻塞态。
  4. 阻塞态 → 就绪态:进程等待的事件发生(如 I/O 操作完成、中断结束),由中断处理程序将其转为就绪态。

image-20260228011907393

进程从运行态变为阻塞态是主动行为,而从阻塞态变为就绪态是被动行为,需要其他相关进程协助(如中断处理程序)。

就绪态和等待态是进程生命周期中最常见的两种状态,转换次数也最多。

3.进程的组成

(1) 进程控制块

本质与作用

  • PCB 是操作系统为每个进程创建的核心数据结构,是进程实体的一部分,也是进程存在的唯一标志。
  • 它常驻内存,贯穿进程的整个生命周期,系统通过 PCB 感知、控制和管理进程。

主要功能

  • 存储进程的当前状态优先级程序和数据地址等关键信息。
  • 用于进程调度、切换、同步、通信及文件访问等所有操作。
  • 保存进程的处理机环境,确保进程被切换后能从断点继续执行。

核心组成部分

分类主要内容
进程描述信息进程标识符(PID)、用户标识符(UID)等
进程控制和管理信息进程当前状态、优先级、代码入口地址、程序外存地址、运行时间等
资源分配清单代码段 / 数据段指针、文件描述符、I/O 设备信息等
处理机相关信息通用寄存器、地址寄存器、控制 / 标志寄存器、状态字等

组织方式

  • 链接方式:将同一状态的 PCB 链接成队列(如就绪队列、不同阻塞队列)。
  • 索引方式:将同一状态的进程组织在一个索引表中,表项指向相应 PCB(如就绪索引表、阻塞索引表)。
(2) 程序段

程序段就是能被进程调度程序调度到 CPU 执行的程序代码段。

程序可被多个进程共享,即多个进程可以运行同一个程序。

(3) 数据段

一个进程的数据段,可以是进程对应的程序加工处理的原始数据,也可以是程序执行时产生的中间或最终结果。

4.进程控制

在操作系统中,一般把程序控制用的程序段称为原语,原语的特点是执行期间不允许中断,它是一个不可分割的基本单位。

(1) 进程的创建

父子进程关系

  • 父进程创建子进程,子进程可继承父进程资源;子进程撤销时归还资源,父进程撤销时通常一并撤销所有子进程。
  • 触发场景:终端用户登录、作业调度、系统提供服务、用户程序请求等。

创建原语(步骤)

  1. 分配唯一 PID,申请空白 PCB → PCB 不足则创建失败。
  2. 分配运行资源(内存、文件、I/O、CPU 时间等)→ 资源不足则创建失败,进程处于创建态等待资源。
  3. 初始化 PCB:标志信息、处理机状态 / 控制信息、优先级等。
  4. 插入就绪队列,等待被调度运行。
(2) 进程的终止
  1. 终止原因

    • 正常结束:任务完成,主动退出。
    • 异常结束:运行中出现错误(存储越界、保护错、非法指令、超时、算术运算错、I/O 故障等)。
    • 外界干预:操作员 / 系统干预、父进程请求、父进程终止等。
  2. 终止原语(步骤)

    1. 根据标识符检索 PCB,读取进程状态。
    2. 若进程处于运行态,立即终止执行,释放处理机。
    3. 递归终止所有子孙进程。
    4. 回收全部资源,归还父进程或操作系统。
    5. 从所在队列(链表)中移除该 PCB。
(3) 进程的阻塞和唤醒
  1. 阻塞(Block)

    • 触发条件:期待事件未发生(如请求资源失败、等待操作完成、数据未到、无新任务等)。
    • 本质:运行态进程主动调用阻塞原语,转为阻塞态,是进程的主动行为。
    • 阻塞原语步骤:

      1. 找到对应 PCB。
      2. 若为运行态,保护现场,转为阻塞态,停止运行。
      3. 插入对应事件的等待队列,释放处理机给其他就绪进程。
  2. 唤醒(Wakeup)

    • 触发条件:期待事件出现(如 I/O 完成、数据到达),由相关进程调用唤醒原语。
    • 唤醒原语步骤:

      1. 在等待队列中找到对应 PCB。
      2. 移出队列,置为就绪态。
      3. 插入就绪队列,等待调度。
  3. 注意事项

    • Block 与 Wakeup 是一对成对使用的原语,必须配对使用,否则阻塞进程可能永久无法唤醒。

5.进程的通信

(1) 共享存储

核心思想:在通信进程间开辟一块可直接访问的共享空间,通过对该空间的读写操作交换信息。

关键要点

  • 需要使用同步互斥工具(如 P、V 操作)控制读写。
  • 分为两种方式:

    • 低级方式:基于数据结构的共享。
    • 高级方式:基于存储区的共享(操作系统提供共享空间和同步互斥工具,数据交换由用户自行安排)。
  • 注意:进程空间通常独立,需通过特殊系统调用实现共享;进程内线程天然共享空间。
(2) 消息传递

核心思想:以格式化的消息为单位进行数据交换,隐藏通信细节,对用户透明,是当前应用最广泛的机制。

两种方式

  • 直接通信:发送进程直接将消息挂到接收进程的消息缓冲队列上。
  • 间接通信:通过 “信箱”(中间实体)传递消息,广泛应用于计算机网络。

应用场景:微内核操作系统中,内核与服务器之间的通信即采用此机制,也适用于多处理机、分布式系统和计算机网络。

(3) 管道通信

核心思想:以生产者 - 消费者方式通信,数据在管道中先进先出(FIFO)。

关键机制

  • 管道为空时,读进程阻塞;管道写满时,写进程阻塞。
  • 需提供互斥、同步和确定对方存在的协调能力。

Linux 中的管道

  • 本质是一种特殊文件,固定大小为 4KB 的缓冲区。
  • 只能由创建进程的子进程访问,子进程继承父进程的管道。
  • 普通管道为单向通信,双向通信需定义两个管道;数据读取为一次性操作,读取后释放空间。

6.线程和多线程模型

(1) 线程的基本概念
  1. 引入线程的目的
  • 引入进程是为了更好地实现多道程序并发执行,提高资源利用率和系统吞吐量。
  • 引入线程则是为了减小程序并发执行的时空开销,进一步提升操作系统的并发性。
  1. 线程的核心定义
  • 线程可理解为 “轻量级进程”,是基本的 CPU 执行单元程序执行流的最小单元
  • 线程由线程 ID、程序计数器、寄存器集合和堆栈组成,是进程中的一个实体。
  • 线程是被系统独立调度和分派的基本单位,自身不拥有系统资源,仅持有运行必需的少量资源,但可与同一进程内的其他线程共享该进程的全部资源。
  1. 线程的基本特性
  • 一个线程可以创建或撤销另一个线程。
  • 同一进程中的多个线程之间可以并发执行。
  • 线程也有就绪、阻塞和运行三种基本状态,运行时会因相互制约而出现间断性。
  1. 进程与线程的内涵变化
  • 引入线程后,进程的角色转变为除 CPU 外的系统资源分配单元
  • 线程则成为处理机的分配单元
  • 同一进程内的线程切换,时空开销远小于进程间的切换。
(2) 线程与进程的比较
对比维度进程线程
调度(核心)传统 OS 中独立调度 + 资源拥有单位;调度需完整上下文切换,开销大引入线程后独立调度的基本单位;切换代价远低于进程,同进程内切换不引发进程切换
并发性仅进程间可并发进程间、同一进程内多线程间、不同进程的线程间均可并发,并发能力显著提升
拥有资源系统中拥有资源的基本单位,持有完整系统资源不拥有系统资源(仅持运行必需的少量资源),共享所属进程的全部资源(如地址空间)
独立性拥有独立地址空间和资源,除全局变量外,其他进程不可访问对其他进程不可见;同一进程内线程共享地址空间和资源,独立性低
系统开销创建 / 撤销需分配 / 回收 PCB 及内存、I/O 等资源,开销大;切换需完整上下文切换创建 / 撤销、切换开销极小(仅需保存 / 设置少量寄存器);同进程内线程同步通信易实现,无需 OS 干预
多处理机支持单线程进程仅能运行在一个处理机上多线程进程可将不同线程分配到多个处理机并行执行
(3) 线程的属性
  1. 轻型实体
  • 线程不拥有系统资源,但每个线程都有唯一标识符和线程控制块(TCB),用于记录寄存器、栈等执行状态。
  1. 可执行相同程序
  • 不同线程可以执行相同的程序代码,例如同一个服务程序被不同用户调用时,会被创建为不同的线程。
  1. 共享进程资源
  • 同一进程内的所有线程,共享该进程所拥有的全部资源(如地址空间、文件描述符等)。
  1. 独立调度与并发执行
  • 线程是处理机独立调度的基本单位,可并发执行。
  • 单 CPU 系统中,线程交替占用 CPU;多 CPU 系统中,线程可并行占用不同 CPU,缩短进程整体处理时间。
  1. 生命周期与状态变化
  • 线程创建后即开始生命周期,直至终止,期间会经历阻塞态、就绪态、运行态等多种状态变化。
(4) 线程的状态与转换
  • 执行状态
  • 就绪状态
  • 阻塞状态
(5) 线程的组织与控制
  1. 线程控制块(TCB)
  • 作用:与进程控制块(PCB)类似,用于记录和管理线程的控制信息。
  • 主要内容:

    1. 线程标识符
    2. 一组寄存器(程序计数器、状态寄存器、通用寄存器)
    3. 线程运行状态
    4. 线程优先级
    5. 线程专有存储区(线程切换时保存现场)
    6. 堆栈指针(保存局部变量和返回地址)
  • 资源共享:同一进程内的所有线程共享进程的地址空间和全局变量,可互相访问彼此的堆栈。
  1. 线程的创建
  • 线程具有生命周期,由创建而产生,由调度而执行,由终止而消亡。
  • 用户程序启动时,通常只有一个初始化线程,负责创建新线程。
  • 创建新线程时,需调用线程创建函数,并提供入口指针、堆栈大小、优先级等参数,函数返回线程标识符。
  1. 线程的终止
  • 线程完成任务或运行异常时,可调用终止函数结束运行;系统线程可能持续运行。
  • 线程终止后,通常不会立即释放资源,需在其他线程执行分离函数后,资源才会被回收利用。
  • 被终止但未释放资源的线程,可被其他线程调用并恢复运行。
(6) 线程的实现方式

image-20260228234207798

  1. 用户级线程(ULT)
  • 管理方式:线程管理(创建、撤销、切换)全部在用户空间完成,内核完全感知不到线程的存在。
  • 调度特点:系统仍以进程为单位进行调度,同一进程内的所有线程共享该进程的时间片。
  • 优点:

    • 线程切换无需进入内核态,节省了模式切换开销。
    • 调度算法可由进程自定义,灵活性高。
    • 实现与操作系统平台无关,可移植性好。
  • 缺点:

    • 一个线程执行系统调用导致阻塞时,整个进程内的所有线程都会被阻塞。
    • 无法利用多处理器优势,一个进程在同一时间只能有一个线程在 CPU 上执行。
  1. 内核级线程(KLT)
  • 管理方式:线程管理全部在内核空间完成,内核通过线程控制块(TCB)感知并控制线程。
  • 调度特点:内核直接对线程进行调度,线程是独立的调度单位。
  • 优点:

    • 能充分利用多处理器,同一进程的多个线程可并行执行。
    • 一个线程阻塞时,内核可调度同一进程内的其他线程执行。
    • 线程切换速度快、开销小。
    • 内核自身也可采用多线程技术,提升系统效率。
  • 缺点:

    • 同一进程内的线程切换需要从用户态切换到内核态,系统开销相对较大。
  1. 组合方式
  • 实现机制:系统同时支持内核级线程和用户级线程,多个用户级线程可以复用同一个内核级线程。
  • 优势:结合了 ULT 和 KLT 的优点,既可以利用多处理器,又能避免频繁的内核态切换,同时克服了各自的不足。
  1. 主流线程库
  • POSIX Pthreads:可提供用户级或内核级实现,是类 UNIX 系统的标准。
  • Windows API:专用于 Windows 系统的内核级线程库。
  • Java 线程 API:通常依赖宿主系统的线程库实现,在 Windows 上用 Windows API,在类 UNIX 系统上用 Pthreads。
(7) 多线程模型

image-20260301002943085

  1. 多对一模型(M:1)
  • 映射方式:多个用户级线程映射到同一个内核级线程。
  • 管理方式:线程调度和管理在用户空间完成,仅当访问内核时才绑定到内核级线程,且一次只允许一个线程映射。
  • 优点:线程管理在用户空间进行,效率较高。
  • 缺点:一个线程因内核访问阻塞时,整个进程都会阻塞;同一时刻只有一个线程能访问内核,无法利用多处理器并行。
  1. 一对一模型(1:1)
  • 映射方式:每个用户级线程都对应一个独立的内核级线程。
  • 优点:一个线程阻塞时,可调度其他线程运行,并发能力强;支持多处理器并行执行。
  • 缺点:创建用户线程时需同步创建内核线程,系统开销较大。
  1. 多对多模型(M:N)
  • 映射方式:将 n 个用户级线程映射到 m 个内核级线程(n ≥ m),通过复用内核线程实现。
  • 特点:

    • 克服了多对一模型并发度不高的问题。
    • 避免了一对一模型中线程创建开销过大的缺点。
    • 结合了前两种模型的优点,在并发能力和系统开销之间取得了平衡。
分类: 操作系统 标签: 操作系统

评论

暂无评论数据

暂无评论数据

目录