13180 操作系统 第三章 进程/线程模型

572 阅读21分钟

开始13180 操作系统的学习过程,献给每一位拥有梦想的"带专人",

ps:有不正确的地方麻烦更新在评论区,我会一一修复 😅

第二章 进程/线程模型

1. 进程

进程是具有一定独立功能的程序在某个数据集合上运行的活动,是操作系统进行资源分配和调度的单位

从操作系统的角度来看,可将进程分为用户进程和系统进程,系统进程的优先级高

进程与程序的区别与联系

  1. 进程和程序的联系

    程序是进程的组成部分之一,一个进程的目标是执行它所对应的程序,如果没有程序进程就失去了意义。从静态角度来看,进程是由程序、数据和控制块(PCB)组成的

  2. 进程与程序的区别

    程序是静态的,进程是动态的。

    程序是永久存在的,进程是为了程序的一次执行而短暂存在的

    一个进程可以包含若干程序的执行,一个程序也可以产生多个进程。

    进程具有创建其它进程的功能。被创建的进程称为子进程,创建者称为父进程。

    例如:一个编译程序在执行时就要执行词法分析、语法分析、代码生成和优化等若干个程序。而一个编译程序有时需要同时生成几个编译进程,为几个用户服务。

可再入程序

一个能被多个用户同时调用的程序,在执行中自身不可以改变

通俗讲:可再入程序必须和有关的数据区分离

进程的特征

  1. 并发性

    多个进程可以同时运行,互不干扰。

  2. 动态性

    进程有生命周期,从创建到消亡,状态会不断变化。

  3. 独立性

    每个进程是独立的资源分配和运行单位。

  4. 交互性

    进程之间可以通过通信或共享资源进行交互。

  5. 异步性

    进程独立运行,进度不可预测。

  6. 结构性

    由程序、数据和控制信息(PCB)组成。

    并动态交互,异步独立结构

2. 进程状态及状态转换

三状态进程模型

image.png

image.png

  1. 运行状态

    进程已获得 CPU 并已在 CPU 上执行。在单 CPU 系统,最多只有一个进程处于运行状态

  2. 就绪状态

    已满足运行条件,但因未获得 CPU 而等待分配。多个进程可同时处于就绪状态。

  3. 阻塞状态

    也称等待状态封锁状态,因等待资源或事件而暂停运行(如等待文件输入或竞争资源失败)。等待条件消失后,转为就绪状态,可再次争取 CPU。

状态转换

  1. 就绪 → 运行

    就绪进程因获得 CPU 开始运行,调度程序按算法分配 CPU,并启动进程运行。

  2. 运行 → 就绪

    时间片耗尽,触发超时中断,保存进程现场,将其状态设为就绪,等待重新调度。

  3. 运行 → 阻塞

    进程因等待资源(如文件输入)暂停运行,保存现场,标记阻塞原因,CPU 转给其他就绪进程。

  4. 阻塞 → 就绪

    阻塞条件解除,进程转为就绪,等待 CPU 分配后继续运行。

五状态进程模型

image.png

  1. 运行状态

    已获得 CPU 资源,正在执行代码。

    当系统无其他可运行进程时,执行系统的空闲进程

  2. 就绪状态

    已具备运行条件,等待 CPU 分配。

    就绪进程通常按优先级排队,可能形成多个优先级队列。

  3. 阻塞状态

    因等待 I/O 或同步事件暂停执行,即使分配到 CPU 也无法运行。

    进入阻塞队列,按事件分类,等待条件解除。

  4. 创建状态

    系统为进程分配资源、加载程序、建立控制块,但进程尚未投入运行

  5. 退出状态

    进程执行结束,系统回收资源并传递相关信息给父进程。

操作系统中多个进程的并发执行时通过交替进入运行状态来实现的

五状态模型状态转换方式

  1. 调度与超时:当一个运行状态的进程超时后,放入低优先级就绪队列,并修改其状态为就绪状态,然后调度另一个就绪状态的进程进入运行状态
  2. 调度、等待事件、事件出现:当一个处在运行状态的进程需要等待某个事件的发生时,主动放弃 CPU,进入阻塞状态;调度另一个就绪状态的进程进入运行状态,当上一个进程等待的事件出现后将相应从阻塞状态队列取出,放入高优先级就绪队列,将状态改为就绪状态

状态转换

  1. 创建新进程

    产生一个新进程,用于运行某程序,例如用户登录或系统创建服务。

  2. 提交

    新进程创建完成,进入就绪状态等待 CPU 分配。

    系统可能限制并发进程数以优化性能。

  3. 调度运行

    从就绪队列中选择进程分配 CPU,进入运行状态。

  4. 释放

    进程因完成任务或出现问题终止,进入结束状态

    正常退出:任务完成。

    异常退出:如内存不足、非法操作或被其他进程终止。

  5. 超时

    时间片用尽或高优先级进程抢占 CPU,当前进程暂停运行,返回就绪状态。

  6. 事件等待(进入阻塞状态)

    等待资源或事件(如 I/O 操作、通信),暂时无法继续执行。

  7. 事件出现(进入就绪状态)

    等待的事件完成或条件满足,阻塞状态解除,返回就绪队列。

七状态进程模型

image.png

五状态进程模型没有区分进程地址空间是外存还是内存,在操作系统中引入虚拟存储管理技术后,需要进一步区分进程的地址空间状态

出现的原因:由于进程之间存在优先级,低优先级的进程等待时间可能较长,为了内存充足,将低优先级的进程移动到外存

优点

  1. 提高处理机效率

    就绪队列为空时,可利用空闲内存提交新进程,提高处理器使用率。

  2. 灵活内存分配:资源不足时,可将部分进程移至外存,为运行进程腾出内存。

  3. 有利于调试:调试时可挂起目标进程,方便对其地址空间进行操作。

对比五状态进程模型增加了两个状态

  1. 就绪状态:进程在内存且可立即进入运行状态
  2. 阻塞状态:进程在内存并等待某事件的出现
  3. 阻塞挂起状态:进程在外存并等待某事件出现
  4. 就绪挂起状态:进程在外存,但只要进入内存,即可运行

七状态进程模型中,新引入的状态转换有挂起和激活两类,意义有变化的转换有事件出现进程提交

  1. 挂起:进程从内存移到外存

    阻塞到阻塞挂起:内存不足时,为提交新进程或运行就绪进程。

    就绪到就绪挂起:有高优先级阻塞,挂起低优先级就绪进程。

    运行到就绪挂起:抢占式系统中,为高优先级进程腾内存。

  2. 激活:进程从外存移回内存

    就绪挂起到就绪:优先级高于当前就绪进程或无就绪进程。

    阻塞挂起到阻塞:内存释放,且事件可能即将出现。

  3. 事件出现:进程等待的事件发生

    阻塞到就绪:事件满足,内存中的进程。

    阻塞挂起到就绪挂起:外存中进程的事件满足。

  4. 进程提交:完成新进程创建,进入就绪或就绪挂起状态(维持较大就绪队列)。

3. 进程控制块

为了便于系统控制和描述进程的活动过程,在操作系统内核中定义了一个专门的数据结构,称为进程控制块 PCB

PCB 的内容

  1. 调度信息:进程名和进程号共同标识一个进程,一个进程的进程号必须是唯一的
  2. 现场信息:进程的运行情况,每个进程都有自己的专用的工作存储区,其他进程运行时不会改变它的内容

进程的组成

进程由程序、数据和 PCB 三部分组成,PCB 是进程的灵魂,程序和数据是进程的躯体

PCB 的组织方式

  1. 线性方式

    将所有 PCB 不分状态组织在一个连续的表中

    优点是简单不需要额外的开销,适用于进程数目不多的系统

    缺点是需要扫描整个 PCB 表才能找到需要的PCB

image.png

  1. 索引方式

    具有相同状态的进程,分别设置各自的 PCB 索引表

image.png

  1. 链接方式:指针

image.png

进程队列的分类

  1. 就绪队列

    所有就绪状态的进程都排在就绪队列中

  2. 等待队列

    对于每一个等待事件组成一个队列

  3. 运行队列

    在单 CPU 系统中,整个系统有一个运行队列

image.png

进程队列的组成

进程队列可以用进程控制块的链接来形容

常用的链接方式有单向链接(C 语言的单链表)、双向链接(C 语言中的双向链表)

一个进程从所在队列中退出称为出队

一个进程排入指定队列称为入队

一个进程插入某个进程队列中间称为插队

进程出队的具体过程

  1. 队首进程出队
  2. 非队首(或队尾)进程出队
  3. 队尾进程出队

4. 进程控制

进程有一个从创建到消亡的生命周期,需要对进程的生命周期中的各种状态转换进行控制,称为进程控制。进程控制是通过进程控制原语实现的

原语

​ 由若干条指令组成的指令序列,用来实现某个特定的操作功能。这个指令序列的执行是连续的,具有不可分割性,执行时也不可以间断,直至该指令执行结束

​ 原语必须在内核态下执行,并且常驻内存。

​ 原语和系统调用都可以被进程所调用,两者的差别在于原语具有不可中断性,它是通过其执行过程中关闭中断实现的,而且原语往往被系统进程所调用

用于进程创建的原语一般由创建原语、撤销原语、挂起原语、激活原语、阻塞原语、唤醒原语、改变进程优先级原语

  1. 创建原语

    创建一个新的进程。创建一个进程的主要任务是建立 PCB。

    创建进程的具体操作是:先申请一个空闲 PCB 区域,将有关信息填入 PCB,置该进程为就绪状态,将其插入就绪队列中

  2. 撤销原语

    释放进程所占用资源,撤销进程实质上就是撤销 PCB

  3. 阻塞原语

    进程从运行状态转换为阻塞状态

  4. 唤醒原语

    一个进程因为等待某个事件而发生阻塞,当该事件发生后,使用唤醒原语将该进程转化为就绪状态

5. 线程

线程的引入

image.png

​ 进程是调度的基本单位还是独立分配资源的单位,如果可以将这两个基本单位的功能分开,即作为调度和分派的基本单位,不作为独立分配资源的单位,则可以让进程轻装运行,面对拥有资源的基本单位,不频繁的对其进行切换,可以提高并发程度并避免消耗过多的系统资源

什么是线程

线程是进程中的一个实体,是CPU调度和分派的基本单位(重点)。

​ • 资源:线程自身只拥有少量资源(如程序计数器、寄存器和栈),但可以共享进程的全部资源。

​ • 特性:线程之间可并发执行,同一进程的线程可相互创建和撤销(重点)。

线程的属性

  1. 唯一标识与描述表

    每个线程有唯一标识符和线程描述表,记录其执行的寄存器、栈等状态信息(重点)。

  2. 执行独立性

    不同线程可以执行相同程序,例如同一个服务被多个用户调用时,系统为其创建多个线程(重点)。

  3. 共享内存

    同一进程内的线程共享进程的内存空间(重点)。

  4. 调度单位

    线程是独立的调度单位,支持并发执行:

​ • 单处理器系统:线程交替占用 CPU。

​ • 多处理器系统:线程可并行运行,减少总时间(重点)。

  1. 生命周期

    线程从创建到终止,会经历阻塞就绪运行三种状态(重点)。

简化总结:线程是共享进程资源的调度单位,有独立标识和状态描述表,支持并发和并行,生命周期包含阻塞、就绪、运行三种状态。

引入线程的好处

  1. 创建快,开销低

    创建线程无需分配资源,比创建进程更快,系统开销更少(重点)。

  2. 切换效率高

    线程间切换速度比进程切换快(重点)。

  3. 通信高效

    同一进程内线程共享内存和文件,线程通信无需调用内核,速度快、机制简单(重点)。

  4. 并行能力强

    线程可独立执行,充分利用处理器和外部设备的并行工作能力(重点)。

简化总结:线程的创建、切换速度快,通信简单高效,并能充分发挥并行性能。

线程的组成

线程控制块 (thread 结构) 简化版

用于保存线程私有信息。

组成

​ 1. 线程描述符:唯一标识线程的编号。

​ 2. 寄存器组:记录线程运行状态,包括程序寄存器、状态寄存器、通用寄存器。

​ 3. 双栈指针

​ • 内核栈指针:线程切换到内核态时使用。

​ • 用户栈指针:线程在用户态执行时使用。

​ 4. 私有存储区:存储线程的现场保护信息和相关统计数据。

记忆重点

线程控制块包含 唯一描述符寄存器组双栈指针私有存储区

线程必须在某个进程内执行,它所需的资源都由它所属的进程拥有,操作系统分配资源时以进程为单位

一个进程可以包含多个线程。传统的进程只有一个线程。当一个进程包含多个线程时,这些线程,除各自私有的少量资源外,还要共享所属进程的所有资源

线程与进程的关系

线程具有许多传统进程所具有的特征,所以线程又称为轻量级进程进程元;传统的进程称为重量级进程

线程与进程比较

  1. 调度

    线程是 CPU 调度的基本单位,进程是资源分配的基本单位

  2. 并发性

    引入线程后,操作系统的并发性变得更强

  3. 拥有资源

    只有进程才拥有资源,一个进程中的所有线程共享进程中的资源

  4. 系统开销

    线程调度的系统开销远小于进程调度的系统开销

线程的实现方式

线程的分类

  1. 用户级线程

image.png

用户级线程由应用程序管理,与操作系统内核无关。

存在于用户空间:线程创建、切换、撤销均在用户空间完成,无需依赖系统调用。

内核感知:内核无法识别用户级线程,仅管理普通进程。

优点

  1. 切换速度快:线程切换无需陷入内核,性能高效。
  2. 灵活调度:应用程序可使用专用调度算法,满足特殊需求。
  3. 兼容性强:适用于任何操作系统,包括不支持线程机制的系统。

缺点

  1. 阻塞问题
    1. 典型系统调用为阻塞式。
    2. 当某线程因系统调用阻塞时,同一进程内所有线程均被阻塞。
  2. 多处理器劣势
    1. 单用户级线程在多处理器系统中无法并行,内核一次仅为一个进程分配一个处理器。
    2. 同一进程内其他线程需等待当前线程释放 CPU。

记忆重点

优点:切换快、灵活调度、跨系统兼容。

缺点:阻塞影响整体、无多处理器优势。

  1. 内核级线程

image.png

线程的创建、切换和管理均由操作系统内核负责,内核感知线程的存在并通过线程控制块(TCB)进行管理。

特点

​ • 依赖内核:线程操作(如创建、撤销、调度)均需通过内核完成。

​ • 系统支持:内核为每个线程保留独立的线程控制块,以感知和管理线程。

优点

  1. 多处理器并行支持

    在多处理器系统中,内核能同时调度同一进程中的多个线程,实现真正的并行操作

  2. 阻塞问题缓解

    若进程内一个线程阻塞,内核可调度该进程中的其他线程继续执行。

  3. 内核线程本身可多线程

    支持高并发任务处理。

缺点

  1. 切换开销大

    线程切换需从用户态转至内核态,增加控制转移的成本。

  2. 固定调度算法

    线程调度由内核控制,应用程序无法自定义线程切换策略。

记忆重点

优点:多处理器支持、阻塞可切换、线程并发高效。

缺点:切换耗时、调度算法受限。

  1. 混合方式实现的线程

    线程创建在用户空间完成,线程调度在核心空间完成

    线程实现方式的比较

    1. 线程的调度与切换速度

      用户级线程切换的速度特别快

    2. 系统调用

      1. 用户级线程

        行为

        用户级线程的系统调用由进程控制,内核不了解用户级线程的存在。

        结果

        • 当一个线程执行系统调用时,内核认为这是整个进程的行为,因此会阻塞整个进程。
        • 其他线程无法执行,导致低效率。
      2. 内核级线程

        行为:内核感知线程的存在,系统调用被识别为单个线程的行为。

        结果

        • 当某线程因系统调用被阻塞时,内核可调度同一进程的其他线程运行。
        • 提升并发度和系统资源的利用率。
    3. 线程执行时间

      • 用户级线程系统,调度是以进程为单位的
      • 内核级线程系统,调度是以线程为单位的

6. 协程

当线程的数量非常大的时候,系统线程会占用非常多的内存空间,过多的线程切换会占用大量的系统时间。为了解决这两个问题,许多编程语言提出了协程机制,例如 C++语言、Python 语言、Go 语言。

协程是运行在线程之上的轻量级线程,当一个协程执行完成后,可以选择主动退出,让另一个协程运行在当前线程之上。协程并没有增加线程的数量,只是在线程的基础上通过分时复用的方式运行多个协程,而且协程的切换在用户态完成,切换的代价比线程从用户态到内核态的代价小很多

练习

  1. 当阻塞队列中唯一的一个进程所等待的事件发生后,该进程应转变为

    1. 运行状态
    2. 就绪状态
    3. 阻塞状态
    4. 退出状态

    对于处于等待状态的进程,在其被阻塞的原因获得解除后,其状态将变为就绪,仅当得到CPU是,才可恢复运行

  2. 某进程已获得处理器外的所有资源,正等待分配处理器资源,此时进程处于

    1. 运行状态
    2. 创建状态
    3. 等待状态
    4. 就绪状态
  3. 正在运行的进程,由于规定的时间片用完而使得系统发出超时中断请求,此时进程状态被修改为

    1. 就绪状态
    2. 阻塞状态
    3. 就绪挂起状态
    4. 阻塞挂起状态
  4. 为了实现对进程的管理,系统通常将相同状态的进程分别组成就绪队列、等待队列和运行队列

  5. 原语和系统调用都可以被进程所调用,两者的差别在于原语具有不可中断性,它是通过在其执行过程中关闭中断来实现的

  6. 进程控制通常采用原语来实现,当某进程在执行过程中需要执行 I/O 操作时,系统使用阻塞原语;当进程所等待的事件发生后,系统使用唤醒原语将其转换为就绪状态

  7. 以下关于线程的属性的叙述中,正确的是

    1. 每个线程有多个标识符和一张线程描述表
    2. 同一个进程中的各个线程共享该进程的内存地址空间
    3. 不同的线程不可以执行相同的任务
    4. 多个线程是不可以并发执行的
  8. 以下关于引入线程的好处叙述中,不正确的是

    1. 线程能独立执行
    2. 线程之间切换花费时间少
    3. 创建一个新线程花费的时间少
    4. 线程之间相互通信包含多种通信机制
  9. 同一个进程的多个线程共享该进程的内存地址空间和文件,它们之间的同步和通信无需调用内核,实现容易且开销小

  10. 为实现进程管理,系统采用链接方式对所有的进程控制块(PCB)进行组织。其中,单向链接方式只有一个指针,前一进程的PCB中的指针值为下一个进程的PCB的地址;双向链接方式包含2 个指针,分别指向前一个进程的地址和后一个进程的 PCB 地址。

  11. 对于只设置了用户级线程的系统,调度的进行单位是

    1. 线程
    2. 管程
    3. 通道
    4. 进程
  12. 线程的实现方式不包括

    1. 混合实现方式
    2. 内核级线程
    3. 商业级线程
    4. 用户级线程
  13. 以下关于用户级线程的叙述中,不正确的是

    1. 用户级线程依赖于内核
    2. 用户级线程只存在于用户态中
    3. 用户级线程包可以在不支持线程的操作系统上实现
    4. 用户级线程允许每个进程有自己定制的调度算法
  14. 内核级线程的创建、撤销和切换由内核实现,每个进程都对应一个线程控制块,系统根据它来感知线程的存在并对它进行控制

  15. 在线程的两种实现方式中,不依赖于内核的是用户级线程,而所有线程的创建、撤销和切换都由内核实现的是内核级线程

  16. 以下关于线程的陈述中,错误的是

    1. 内核不知道用户级线程的存在
    2. 无论何种线程,其切换都需要内核的支持
    3. 在支持线程的系统中,线程是调度和分派的基本单位
    4. 无论系统是否支持线程,进程都是资源分配的基本单位

捏捏捏捏捏捏捏捏捏捏捏

笔者观看的课程是 B 站博主小飞学长Pro 课程,前四章是免费的如果需要看后面的建议大家去购买正版课程 😊😊

🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉