2.1 进程

1.进程的概念,特征和组成

a.进程的概念和特征

==程序:是静态的==,存放在磁盘里的*==可执行文件==*(一系列指令集合)。

==进程(process):动态的==(最本质的区别),是==程序的一次执行过程==。

==进程实体(进程映像):是静态的==,是进程在某一时刻的状态。

进程支撑起了OS两大基本特性:并发性和共享性。

  • 解决了:①失去封闭性。②执行过程间断性。③结果不可再现性。

生命周期:一个进程在生命周期内可以执行一个或多个程序。

区别“一个进程**==执行==多个程序”≠“一个进程==运行==**多个程序”

  • 串行执行:一个时刻只执行一个程序,是==先后替换关系==
  • 不是并行:==不是同时运行==多个程序(那是多线程或多进程的事)
一个进程==执行==多个程序 同一个进程(PID 不变),先后运行不同的可执行文件
父子进程 一个进程创建另一个新进程(pid不同),==父子进程并发地执行,且不共享虚拟地址==
进程切换 CPU 在不同进程之间轮换执行,由操作系统调度

题目1:⭐

​ A. 一个进程在其生命周期中可执行多个程序√(见part1)

​ B. 一个进程在同一时刻可执行多个程序×

​ C. 一个程序的多次运行可产生多个进程√(打开多个网页)

​ D. 一个程序的一次执行可产生多个进程√(eg通过系统调用如fork()创建新的进程,此时就有了父进程和子进程)

题目2:

​ 进程之间可能有相关性,也可能是相互独立的。

​ 进程的相关性:血缘关系(父子) 或 协作关系(进程间通信)

进程的特征(相比于程序)

==动态性。==并发性。独立性。异步性。结构性。

==异步性:==并发进程每次运行时可能会有不同的结果。(执行速度的不同会造成进程执行顺序和冲突等问题)

image-20260325193602202

b.进程实体 的组成(逻辑视角)

进程实体 == PCB + 程序段 + 数据段

PCB(process control block ==进程控制块==)

  • OS对进程进行管理工作所需的信息都保存在进程中。

  • ==PCB是进程存在的唯一标志==。当进程被创建时,os为其创建PCB,当进程结束时,会回收PCB。

    • PID:OS在创建一个进程时候,会给其一个ID,即PID。(用于区分同一软件的不同进程)
  • ==PCB有四个部分:== ①进程标志信息。②进程控制信息。③资源分配信息。④CPU现场信息(各种寄存器的值) /上下文信息。

    • 不包括:全局变量。

image-20260325192211120

程序段、数据段

PCB是给OS用的。

程序段、数据段是给进程自己用的。

程序段:程序的指令。【进程间的程序段可以共享】

数据段:运行过程中产生数据。(运行时细分 – 数据段+堆+栈+共享库)【每个进程的数据段是私有的】

  • EG:同时挂3个QQ,PCB和数据段不同,==但是程序段相同。==

c.进程的内存映像(运行时布局)

概念:程序被加载运行时,OS会为其建立一个**==虚拟的内存空间。==**

构成:

  • ==代码段==:可执行==指令==、只读==常量==。
  • ==数据段==:==全局变量,静态变量==。
  • ==数据堆==:==动态内存==。(用malloc分配)(可动态扩展和收缩,向上增长)
  • ==数据栈==:存放==局部变量==,==函数参数==等临时信息。(可动态扩展和收缩,向下增长)
  • 共享库的存储映射区:存放内存映射文件。

==**进程控制块(PCB)**,不属于进程的虚拟地址空间,而是存放在内核区==,对用户不可见。

image-20260328163340254

回顾

image-20260325193721980

2.进程的状态与转换

进程/线程的状态:==创建 → 就绪 → 运行 → 阻塞 → 终止==

进程在 CPU 上的执行不是连续的(进程切换,阻塞…)

但进程的生命周期(从创建到终止)本身是连续的

进程的状态

==创建态:==进程被创建时,OS为进程分配资源,初始化PCB

  • ==创建进程的原因有:==①用户登录,②高级调度,③系统处理用户程序的请求,④用户程序的应用请求。
    • (设备分配:不会创建进程,是IO部分的事情。)

==就绪态:==进程创建完成后,为“就绪态”。**==有资源,无CPU。==**(CPU忙)

image-20260325195907267

==运行态:== ==有资源 + 有CPU。==

image-20260325200034574

==阻塞态:==

  • 进程运行过程中,请求等待某个事件的发生 / 资源分配。(eg打印机响应)。
  • 在事件发生前,进程无法继续执行,OS会让进程下CPU,并让它进入阻塞态,别的进程上CPU。
  • 进入阻塞态后:==无CPU + 无资源==
image-20260325200347501

==终止态:==进程执行exit系统调用,请求OS终止该进程,此时进程进入终止态。OS回收进程。

image-20260325195115467

进程状态的转换

运行态→阻塞态,是==主动行为==。【由自身发起的系统调用触发。因此只有处于运行态的进程才能执行阻塞操作。】

阻塞态→就绪态,是==被动行为==。

==when运行态→就绪态==: ①时间片到时(==主动让出CPU)。②出现了进程优先级更高的进程。

==when运行态→阻塞态==:==① 进程主动等待资源分配(如IO,互斥/同步数据)。②或者等待某个事件发生(如sleep,wait)

image-20260325194759219

题目2:

​ when一个进程状态的变化会引起 另一个 进程的变化:运行态→终止态

​ when一个进程状态的变化不会引起 另一个 进程的变化:阻塞态→就绪态

题目3:

​ (在分时系统中)处于就绪态的进程最多。(都在等待CPU,而阻塞态一般不会太多)

进程的组织

在实际OS中,通常存在着大量的进程,为进行调度和管理,OS将各进程的PCB以某种方式组织起来。

链接方式:系统将处于相同状态的PCB通过指针链接成一个队列。

索引方式:系统为每种状态建立一个索引表(本质上是一个数组),表项指向对应状态的PCB。

image-20260325195304189 image-20260325195336096

回顾

image-20260325195452930

3.进程控制

a.进程控制和实现

==进程控制:实现进程状态转换==

==如何实现:用“原语”实现==

  • 用原语的原因:原语的执行具有“原子性”,即“一气呵成”。【防止在第①步接收中断信号,导致信息不统一的情况。】
    • 如何实现原语的“原子性”:通过特权指令“关中断”和“开中断”(屏蔽了外部中断信号)

==注:原语是一种特殊的程序。==

image-20260325205335582

b.进程控制相关的原语

创建原语

  • (允许一个进程创建另一个进程)子进程和父进程是相互独立⭐的实体,拥有各自的PCB和地址空间。
    • ==父子进程:独立但需通信,开销大但安全可靠。==(fork())
    • 进程与线程:共享但需同步,开销小但需谨慎管理并发安全。
  • 引起进程创建的操作:用户登录。作业调度。提供服务。应用请求。(设备分配是数据结构实现的,no)

image-20260325210123068

撤销原语

image-20260325210559548

进程终止时,不同操作系统的对子进程的处理方式:

  • 有的系统子进程终止。
  • 有的系统(如Linux系统)子进程不终止而是由init进程(pid=1)收养继续执行。

阻塞原语和唤醒原语

  • 阻塞原语往往包含“状态修改 + 调用切换原语”两个步骤

    • 而切换原语也可以由其他原因触发(如时间片用完)
  • ==阻塞和唤醒两个原语必须成对使用。==

  • 某进程退出 临界区 后,之前因需要进入该临界区而被阻塞的有关进程会被唤醒

    • 临界资源,一次只能给一个进程所用。

image-20260325210814417

切换原语

image-20260325211011458

回顾

image-20260325212003186

4.进程通信

一个行不通的方法是全局变量,因为全局变量是相对于某一个进程而言的,不同进程有不同的全局变量。

==进程通信:两个进程之间产生数据交互==(eg抖音分享视频到微信)

进程通信需要OS支持:because各个进程拥有的内存地址空间是相互独立的

根据通信效率和数据量的不同,分为:

  • 低级通信:传递控制信息(如同步,互斥),如PV操作。
  • 高级通信:高效 传输大量数据。包括共享存储,消息传递和管道通信。

a.共享存储(2)

​ – A.基于存储器的共享

==申请一片共享内存区==,并映射到进程的虚拟地址空间。

需保证==各个进程对共享空间的访问是互斥的==。 (程序员/高级库/进程通过调用OS提供的同步原语来保证互斥,==通信进程自己实现互斥==)

共享存储是三种方式中==数据传输速度最快==的。(消息传递和管道都需通过内核中转)

(OS只负责分配,不提供同步保护)

image-20260325212851945

​ – B.基于数据结构的共享

image-20260325213126018

b.消息传递(2)

==数据交换 以==格式化的消息==(消息头,消息体)为单位。==

==进程通过==OS提供的==“发送消息/接收消息” 两个原语 进行数据交换==。

(目前广泛应用,eg微内核与服务器之间的交互就是基于消息传递)

image-20260424134545418

直接通信方式

指明发送给谁,谁接收。

image-20260325213704700

间接通信方式

以“信箱”作为中间实体进行消息传递。没有指明发送对象。

image-20260325214027775

c.管道通信(1)

是一个特殊的 ==共享文件(pipe)==

  • 但并非储存在磁盘中的文件,==是在 内存 中开辟出一个大小固定的内存缓冲区。==【与磁盘无关】

相比于共享存储通信方式:是FIFO的。单向的。**==【一条管道是半双工通信==】** (读取数据是一次性的)**==【共享存储是很多个收发口】==**。

①各进程互斥地访问管道**==【OS负责实现互斥】==(所以理论上是可以多进程访问的**,但是容易出错,所以用互斥保证单线程访问 )

②管道写满时,写进程将阻塞(读端read()返回0),till读进程取走部分数据。

②管道读空时,读进程将阻塞,till写进程写入新数据。【由此可见是固定大小的】**==【自动阻塞与唤醒】==**

image-20260325215307101

image-20260325215318560

回顾

image-20260325215808045

d.信号

用于通知进程某个特定事件已经发生

image-20260325220002230

基本概念:某个事件发生后,OS向进程发送信号。

image-20260325220200178

实现原理:

A.信号的发送

用户进程之间可以发送信号(受权限限制)

OS内核也可以给用户发送信号(如异常、除零错误,定时器超时等)

进程也可以给自己发送信号

image-20260325220736536

B.信号的保存和处理(when)

信号不是立即处理的,先保存在PCB中。

==进程从内核态返回用户态时==,会检查pending表。如果有信号,就==处理信号。==

  • 优先处理序号较小的信号

image-20260325221359274

C.信号的处理(HOW)

  • ① 执行OS为此类信号设置的(默认)缺省信号处理程序(不过有的信号默认忽略不用处理)
  • ② 执行进程为个别信号设置:用户自定义信号处理程序(将覆盖掉①)
    • 自定义信号处理程序只能在自己的进程使用。
    • 有些信号不支持自定义处理程序。(只能执行系统默认的处理程序)

image-20260325221949097

image-20260325221501641

Notes:

某个进程要阻塞的信号也不一样,自定。

image-20260325222127559

==信号可以作为异常的配套机制,让进程对OS的异常处理进行补充==

  • (当有的异常,OS无法由内核全部处理时,可能还需要用户进程的配合)

image-20260325222405583

回顾⭐

image-20260325222739958

5.线程

基本概念

image-20260326115720468

线程 – 使进程并发pro

概念:

  • 线程 ==不拥有== 独立的 ==系统资源(如(内存)地址空间,代码,数据)==

    • 资源通过共享的方式获取。(eg代码段,数据段..)
  • 但 ==拥有== 运行所必须的**==私有数据结构TCB==【包括:线程ID,CPU现场(PC,寄存器集合),栈…】

  • 线程==可以独立执行程序==,但是==不能脱离进程进行==

进程VS线程:

  • 线程变成了**==CPU调度和分派==的基本单位**(最小单位)。(内核级线程)
  • 进程是**==资源分配==的基本单位**(eg打印机,内存分配)

线程优点:

  • ==并发粒度更细==。(不仅仅进程能并发了,线程直接也能并发)

  • ==系统开销变小==。(同一进程内的切换开销 小于 进程的切换开销)

线程缺点:

  • ==无法增强进程安全性==(线程出错可能影响进程)

注意:

  • 不能无约束地并行,得有互斥和同步,以免造成数据不一致。
image-20260327160601223

线程的属性

image-20260327161313052

线程的实现方式(2to3)

image-20260327161430185

用户级 线程⭐

早期的线程os创建不了线程,是==线程库/用户程序实现的线程==。【不依赖于OS的支持,**==即不需要切换到内核态,在用户态实现的==**】

优点:①==效率高==(线程的切换不需要变态(到核心态))②调度策略由应用程序定制。③==有可移植性==(可以在任何操作系统中,不经修改,直接运行)

缺点:①==一个线程被阻塞,这个进程都会被阻塞,并发度不高==。②==利用不了多CPU的并行性==。

image-20260327161715071

内核级线程

OS支持的线程,内核级线程。

==OS会为每个内核级线程建立相应的TCB==(thread control block),通过TCB对线程进行管理。

优点:①(同一个进程的)多线程可在多核处理机上运行。②阻塞处理灵活。③并发度高(适合I/O 密集型等高阻塞场景)

缺点:==效率低(线程的切换需要变态)==。

注意区分:==用户级线程切换,内核级线程切换==

image-20260328173159146

多线程模型

用户级线程和内核级线程的组合。

一对一模型

一个用户级线程映射到一个内核级线程。

优点:当一个线程被阻塞,别的线程还可以继续执行,并发能力强。

缺点:开销大(变内核态)

image-20260327163313387

多对一模型

多个用户级线程==映射到一个内核级线程==。

优点:用户级线程切换不用变态,开销小,效率高。

缺点:一个用户级线程被堵塞,整个进程被堵塞,并发度低。

image-20260327163656140

多对多模型

n个用户级线程映射到m个内核级线程(n≥m)

优点:==克服了多对一的缺点(整体堵塞)==,==克服了一对一缺点(变态开销大)==

image-20260327163858476

回顾

image-20260327164057331

线程的状态与转换

基本上同进程的状态与转换

image-20260327164235902

线程的组织与控制

image-20260327164420152