OS:进程&线程、死锁


1、进程 & 线程

1.1、联系与区别

进程 线程
含义 一个在内存中运行的应用程序 进程的一个执行任务
包含关系 一个进程有若干个线程,至少包含一个线程 进程的一部分,相当于只有一个任务的进程(也称轻权进程、轻量级进程)
根本区别 操作系统资源分配的基本单位 处理器任务调度和执行的基本单位
资源开销 每个进程都有独立的代码和数据空间(程序上下文),上下文切换的开销大 同一类线程共享代码和数据空间,每个线程有独立的栈区和程序计数器,上下文切换的开销小
内存分配 不同进程间的地址空间和资源相互独立 同一进程的线程共享本进程的地址空间和资源
影响关系 进程崩溃后,在保护模式下不影响其它进程 线程“崩溃”,可能导致整个进程崩溃。
(多进程比多线程健壮)
执行过程 可独立执行,有程序运行的入口、顺序执行序列和程序出口 线程不能独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制

1.2、线程崩溃

线程“崩溃”时触发 segment fault 信号

系统的默认处理方式是终结该线程所在的进程,也可屏蔽信号。

  • 不屏蔽信号:操作系统终止该线程所在的进程。
  • 屏蔽信号:由线程的崩溃位置决定
    • 线程独占区:不影响其它线程。
    • 线程共享区:会的

Java 线程崩溃,JVM 自动释放相关的资源,不会导致进程崩溃。

1.3、线程状态

  • OS 层面:初始、可运行、运行、阻塞、终止。

    image-20220323014842029

  • Java Thread API:NEW、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING、TERMINATED

    image-20220323021543824

2、锁的活跃性

  • 死锁:多个进程在竞争资源或彼此通信而造成的阻塞。
  • 饥饿:某个进程一直得不到资源。

2.1、资源类型

分类标准:可重用、可抢占。

2.1.1、重用性

  • 可重用资源(永久)
    • 可被多个进程多次使用(如硬件)。
    • 一次只能分配给一个进程使用,其它线程必须等待资源释放。
    • 数目:固定,进程无法创建或删除。
    • 使用顺序:请求资源、使用资源、释放资源。
  • 消耗性资源(临时)
    • 进程在运行期间动态的创建和消耗。
    • 数目:进程运行期间是可以不断变化(0 或多个)。
    • 典例:进程间通信的消息。
      • 创建:通常由生产者进程创建,放入该资源类的缓冲区。
      • 消耗:通常由消费者进程消耗,进程可请求若干个资源并消耗,不再放回缓冲区。

2.1.2、抢占性

  • 可抢占资源:被进程获取后,可被其他进程或系统抢占,不会引起死锁(如 CPU、主存)
  • 不可抢占资源:被进程获取后,只能等进程本身释放资源(如打印机)

2.2、死锁

2.2.1、产生原因

  • 竞争不可抢占资源(互斥)
    1. OS 中仅有一台打印机和输入设备,某一时刻进程 P1 使用打印机,P2 使用输入设备。
    2. 此时 P1 请求使用输入设备、P2 请求使用打印机,双方等待彼此的资源。
  • 竞争可消耗资源(循环等待)
    • 三个进程互相发送消息(可消耗资源)
    • 进程 P1 接收 P3 的消息 m3,发送 m1 给 P2;P2 接收 P1 的m1,发送 m2 给 m3;P3 接收 P2 的 m2,发送 m3 给 m1。
    • 若进程先发送再接收,OK。
    • 若进程先接收再发送,死锁。
  • 进程执行顺序:系统进入不安全状态。

2.2.2、特征(必要条件)

只要发生死锁,以下 4 个条件同时成立。

  1. 互斥:至少有一个资源非共享,同一时刻只有一个线程能使用。
  2. 不可剥夺:即不可抢占资源,资源只能在进程完成任务后主动释放
  3. 请求与保持:进程占用至少一个资源,并等待另一个被其它进程占用的资源。
  4. 循环等待:存在进程资源的循环等待链(如进程 P1 等待 P2,P2 等待 P1)

2.2.3、处理

  • 预防
  • 避免
  • 检测
  • 接触

预防

设置限制条件,破坏产生死锁的 4 个必要条件。

  • 互斥:无法破坏
  • 不可剥夺:请求被另一个进程占有的资源被拒绝时,释放当前进程的资源、或抢占资源。
  • 循环等待:有序资源分配法

避免

在资源的动态分配过程中,用某种方法防止系统进入不安全状态。

  1. 有序资源分配法:将资源统一编号,进程必须按编号顺序申请资源。
    • 示例:操作系统中有一个 R1、R2 资源,分别编号为 1、2
    • 进程必须按编号升序申请,即 R1 → R2,不能是 R2→ R1。
    • 破坏循环等待的条件
  2. 银行家算法:允许进程动态申请资源,在资源分配前检查安全性。
    • 拟分配资源给当前进程,计算剩余资源数量是否能满足下一进程的需求。

常用技术

  • 加锁顺序:线程按一定的顺序加锁。
  • 加锁时限:线程尝试获取锁时加上一定的时限,超过时限则放弃对该锁的请求,并释放自己占有的锁。
  • 死锁检测

检测

设置检测机构,及时检测死锁的发生。

解除

检测出死锁后,采取适当措施将进程从死锁状态中解脱出来。

  • 资源剥夺:挂起某些死锁进程并剥夺资源,分配给其它死锁进程。
  • 撤销进程:强制撤销部分或全部死锁进程并剥夺资源。
  • 进程回退:设置还原点,让死锁进程回退到足以回避死锁,进程回退时自愿释放资源而不是被剥夺。