操作系统学习笔记-进程调度篇
文章目录
- 📌 进程(Process)和线程(Thread)的概念
- 1️⃣ 什么是进程(Process)?
- ✅ **定义**
- 🎯 **进程的特点**
- 🔍 **进程示例**
- 2️⃣ 什么是线程(Thread)?
- ✅ **定义**
- 🎯 **线程的特点**
- 🔍 **线程示例**
- 3️⃣ 进程 vs 线程 🆚
- 👨👦 父进程(Parent Process)与子进程(Child Process)
- 1️⃣ **什么是父进程(Parent Process)?**
- ✅ **定义**
- 🎯 **父进程的特点**
- 2️⃣ **什么是子进程(Child Process)?**
- ✅ **定义**
- 🎯 **子进程的特点**
- 3️⃣ **父进程与子进程的关系**
- 4️⃣ **Python 示例代码**
- 🚀 **创建子进程**
- 🧵 线程的分类 & 优势
- 1️⃣ **内核态线程(Kernel Thread)**
- 2️⃣ **用户态线程(User Thread)**
- 3️⃣ **线程的优势**
- 进程调度(Process Scheduling)
- **进程调度的三种方式**
- **抢占式进程 vs 非抢占式进程**
- **1. 抢占式调度(Preemptive Scheduling)**
- **2. 非抢占式调度(Non-Preemptive Scheduling)**
- **总结**
- 1. 周转时间 (Turnaround Time)
- 2. 响应时间 (Response Time)
- 3. 等待时间 (Waiting Time)
- 小结
- 进程调度与作业调度:
- 一、进程(Process)与作业(Job)的区别
- 二、进程调度算法(CPU时间分配)
- 1. 先来先服务(FCFS)
- 2. 短作业优先(SJF)
- 3. 时间片轮转(Round Robin)
- 4. 优先级调度(Priority Scheduling)
- 三、作业调度算法(任务队列管理)
- 1. 先到先得(FIFO)
- 2. 短作业优先(SJF)
- 3. 最高响应比优先(HRRN)
- 4. 多级反馈队列(Multilevel Feedback Queue)
- 四、调度算法的核心目标
- 五、关键总结
📌 进程(Process)和线程(Thread)的概念
1️⃣ 什么是进程(Process)?
✅ 定义
- 进程是程序在计算机中的一次运行实例,是操作系统进行资源分配的基本单位。
- 每个进程都有独立的内存空间、数据、代码 和 系统资源(如文件、网络连接等)。
- 进程之间相互独立,一个进程的崩溃不会影响其他进程。
🎯 进程的特点
- 独立性:每个进程拥有自己独立的内存空间。
- 并发性:多个进程可以在同一时间运行(在多核 CPU 上可以真正并行)。
- 资源占用大:每个进程需要占用一定的系统资源,如内存、文件句柄等。
🔍 进程示例
- 你打开 微信,就是一个进程。
- 你同时打开 Chrome 浏览器,它是另一个进程。
- 你在终端运行
python my_script.py
,这个 Python 解释器本身也是一个进程。
2️⃣ 什么是线程(Thread)?
✅ 定义
- 线程是进程内的执行单元,是操作系统进行CPU 调度的基本单位。
- 一个进程可以包含多个线程,它们共享相同的内存空间和系统资源。
- 线程之间相互协作,能提高程序执行效率。
🎯 线程的特点
- 共享内存:同一进程中的多个线程共享全局变量、代码段,无需额外的进程间通信(IPC)。
- 轻量级:线程切换比进程切换更快,开销更小。
- 并行执行:在多核 CPU 上,多个线程可以真正同时运行,提高计算效率。
🔍 线程示例
- 微信 中,主界面、消息接收、语音通话等功能可能是不同的线程。
- 浏览器 的多个标签页可能是多个线程,而浏览器本身是一个进程。
- Python 中使用
threading
模块可以创建多个线程执行任务。
3️⃣ 进程 vs 线程 🆚
比较项 | 进程(Process) | 线程(Thread) |
---|---|---|
基本概念 | 独立的运行实例 | 进程内部的执行单元 |
资源占用 | 需要独立的内存和资源 | 共享 进程的内存和资源 |
通信方式 | 需要 进程间通信(IPC) | 线程共享 进程数据,直接访问变量 |
创建速度 | 慢,因为需要分配独立资源 | 快,因为不需要重新分配资源 |
稳定性 | 进程崩溃不会影响其他进程 | 线程崩溃可能导致整个进程崩溃 |
并发能力 | 可以真正并行(多进程) | 需要配合 GIL ,在 Python 中伪并行(多线程) |
👨👦 父进程(Parent Process)与子进程(Child Process)
1️⃣ 什么是父进程(Parent Process)?
✅ 定义
- 父进程 是一个已经在系统中运行的进程,它可以创建新的进程(即子进程)。
- 在操作系统中,每个进程都会有一个父进程(除了
init
进程)。 - 创建子进程的方法:
- 在 Linux/Unix 中使用
fork()
- 在 Windows 中使用
CreateProcess()
- 在 Python 中使用
multiprocessing
模块
- 在 Linux/Unix 中使用
🎯 父进程的特点
- 可以创建多个子进程
- 子进程可以继承父进程的资源
- 父进程可以等待子进程完成,也可以让子进程独立运行
2️⃣ 什么是子进程(Child Process)?
✅ 定义
- 子进程 是由父进程创建的新进程,继承了父进程的大部分属性(如文件描述符、环境变量等)。
- 子进程拥有独立的内存空间,但可以与父进程共享部分资源。
🎯 子进程的特点
- 拥有自己的进程 ID(PID)
- 可以执行不同于父进程的任务
- 可以终止自己,也可以被父进程终止
3️⃣ 父进程与子进程的关系
比较项 | 父进程(Parent Process) | 子进程(Child Process) |
---|---|---|
创建方式 | 由操作系统或其他进程创建 | 由父进程创建 |
进程 ID | 由系统分配 | 由系统分配(不同于父进程) |
资源共享 | 可以与子进程共享资源 | 继承父进程的资源,但有独立的地址空间 |
存续关系 | 可以继续运行 | 可能依赖父进程,或独立运行 |
终止情况 | 可以主动终止子进程 | 父进程终止后,子进程可能变成孤儿进程 |
4️⃣ Python 示例代码
🚀 创建子进程
import os
def child_process():
print(f"我是子进程,PID: {os.getpid()},我的父进程是: {os.getppid()}")
if __name__ == "__main__":
print(f"我是父进程,PID: {os.getpid()}")
pid = os.fork() # 创建子进程
if pid == 0:
# 子进程执行
child_process()
else:
# 父进程执行
print(f"父进程(PID: {os.getpid()})创建了子进程(PID: {pid})")
🧵 线程的分类 & 优势
1️⃣ 内核态线程(Kernel Thread)
✅ 定义:由 操作系统内核 直接管理和调度的线程。
✅ 特点:
- 由 内核 创建、管理和调度,用户无法直接操作。
- 线程切换时需要 内核干预,会有上下文切换的开销。
- 适用于 多核 CPU 并行计算,如 Web 服务器、高性能计算。
2️⃣ 用户态线程(User Thread)
✅ 定义:由 用户程序 创建和管理,操作系统 不直接管理。
✅ 特点:
- 线程调度在 用户态 进行,不涉及内核,切换速度快。
- 但如果一个线程阻塞,整个进程都会阻塞。
- 适用于 轻量级任务,如脚本执行、GUI 线程。
3️⃣ 线程的优势
✅ 比进程更轻量级:创建、销毁、切换的开销更小。
✅ 支持并发执行:多个线程可以同时运行不同任务。
✅ 共享资源:同一进程内的线程共享内存,无需进程间通信(IPC)。
✅ 提升 CPU 利用率:减少 CPU 空闲时间,提高任务执行效率。
🚀 总结:
- 内核态线程:更强大,适合高性能计算,但开销大。
- 用户态线程:更轻量,适合轻量级任务,但易受阻塞影响。
进程调度(Process Scheduling)
进程调度是 操作系统管理 CPU 资源 的机制,决定哪个进程可以使用 CPU 以及运行多长时间。
进程调度的三种方式
-
长程调度(作业调度)
- 选择哪些进程进入内存(从磁盘加载到 RAM)。
- 只在新进程创建时发生。
-
中程调度(内存调度)
- 负责进程的挂起(swap out)和恢复(swap in)。
- 用于优化内存,防止内存占用过多。
-
短程调度(CPU 调度)
- 负责选择下一个运行的进程。
- 最频繁 发生,直接影响系统响应速度。
抢占式进程 vs 非抢占式进程
1. 抢占式调度(Preemptive Scheduling)
- 系统可以随时中断 进程,强制切换到另一个进程。
- 特点:
- 更公平,防止某个进程长期独占 CPU。
- 适合多任务系统(如 Windows、Linux)。
- 例子:
- 时间片轮转调度(RR)
- 最高优先级调度
2. 非抢占式调度(Non-Preemptive Scheduling)
- 进程自己决定 何时放弃 CPU,操作系统不会强制打断。
- 特点:
- 适合批处理系统(如老式 DOS)。
- 可能导致 某个进程长时间占用 CPU,影响系统响应。
- 例子:
- 先来先服务(FCFS)
- 最短作业优先(SJF)
总结
调度方式 | 是否可被打断 | 适合场景 |
---|---|---|
抢占式 | ✅ 可以随时被系统强制打断 | 多任务系统,如 Windows、Linux |
非抢占式 | ❌ 进程自己放弃 CPU | 批处理系统,如 DOS |
📌 结论:现代操作系统大多采用 抢占式调度,保证系统流畅性和公平性!
1. 周转时间 (Turnaround Time)
定义:
周转时间是一个任务从提交到完成所经过的总时间。它包括了任务在系统中处理、等待等所有过程所花费的时间。
公式:
周转时间 = 完成时间 - 提交时间
举例:
假设任务 A 提交时间是 10:00,完成时间是 10:30,那么周转时间为 30 分钟。
2. 响应时间 (Response Time)
定义:
响应时间是指从用户发出请求到系统开始响应的时间延迟。这个时间不包括任务的处理时间,只关注系统给出反馈的时间。
公式:
响应时间 = 第一次响应的时间 - 提交时间
举例:
如果用户在 10:00 提交请求,而系统在 10:05 开始响应,那么响应时间为 5 分钟。
3. 等待时间 (Waiting Time)
定义:
等待时间是指一个任务在等待被处理的时间。它不包括任务的执行时间,只考虑任务在队列中等待的时间。
公式:
等待时间 = 周转时间 - 执行时间
举例:
假设任务 B 提交到系统的时间是 10:00,系统在 10:15 开始执行,执行时间是 10 分钟,那么等待时间是周转时间减去执行时间,即:
等待时间 = 周转时间 - 执行时间 = 25 分钟 - 10 分钟 = 15 分钟
小结
- 周转时间 = 任务完成所需的全部时间。
- 响应时间 = 系统对请求的响应延迟。
- 等待时间 = 任务在等待执行过程中消耗的时间。
这些定义帮助我们衡量系统性能,特别是在操作系统和任务调度的上下文中。
进程调度与作业调度:
一、进程(Process)与作业(Job)的区别
概念 | 定义 | 关键区别 |
---|---|---|
作业 | 用户提交给操作系统的任务单元(如一个程序或脚本)。 | 宏观管理:作业是用户视角的任务集合,可能包含多个进程或步骤(如编译、运行)。 |
进程 | 操作系统分配资源(CPU、内存)的基本单位,是作业的执行实例。 | 微观执行:进程是操作系统视角的独立执行实体,具有独立的内存空间和运行状态。 |
示例:
用户提交一个数据分析作业(Job),该作业可能启动多个进程(如数据读取进程、计算进程、结果输出进程)。
二、进程调度算法(CPU时间分配)
1. 先来先服务(FCFS)
- 机制:按进程到达就绪队列的顺序分配CPU,非抢占式。
- 优点:实现简单。
- 缺点:长进程会阻塞短进程(“护航效应”),平均等待时间长。
2. 短作业优先(SJF)
- 机制:优先执行预计运行时间最短的进程,可抢占或非抢占。
- 优点:最小化平均等待时间。
- 缺点:需预知运行时间,长进程可能“饥饿”(长时间得不到执行)。
3. 时间片轮转(Round Robin)
- 机制:为每个进程分配固定时间片(如10ms),超时后强制切换。
- 优点:公平性强,适用于交互式系统。
- 缺点:频繁上下文切换可能降低吞吐量。
4. 优先级调度(Priority Scheduling)
- 机制:为进程分配优先级,高优先级先执行。
- 问题:低优先级进程可能“饥饿”,需结合老化(Aging)技术动态提升优先级。
三、作业调度算法(任务队列管理)
1. 先到先得(FIFO)
- 机制:按作业提交顺序分配资源。
- 缺点:大作业可能阻塞后续小作业,资源利用率低。
2. 短作业优先(SJF)
- 机制:优先调度预计运行时间短的作业。
- 优势:系统吞吐量高。
- 挑战:依赖准确的作业时间预测。
3. 最高响应比优先(HRRN)
- 公式:响应比 = ( \frac{\text{等待时间} + \text{预估运行时间}}{\text{预估运行时间}} )
- 设计目标:平衡等待时间与执行时间,避免长作业饥饿。
4. 多级反馈队列(Multilevel Feedback Queue)
- 机制:
- 将作业分为多级队列,不同队列优先级和时间片不同。
- 新作业进入高优先级队列,若未完成则降级到低优先级队列。
- 优势:兼顾响应速度与吞吐量,适应动态负载。
四、调度算法的核心目标
调度类型 | 核心目标 |
---|---|
进程调度 | 最大化CPU利用率,减少响应时间(如交互式系统需快速切换)。 |
作业调度 | 优化系统吞吐量,平衡资源分配(如批处理系统需高效完成大量任务)。 |
五、关键总结
- 进程是执行的载体,作业是任务的逻辑单元。
- 进程调度关注微观的CPU时间分配,作业调度关注宏观的任务队列管理。
- 算法选择需权衡公平性、效率、响应速度与系统负载特性。