操作系统:CPU管理(进程与线程)

目录

一、操作系统概述

1、操作系统是什么

2、操作系统的核心功能

3、操作系统的内核

二、CPU调度

1、基本概念

1.1 并行与并发的区别

1.2 进程与线程的区别

1.3 进程的状态

1.4 线程的状态

1.5 进程间通信方式

1.6 线程常见问题

1.6.1 死锁

1.6.2 饥饿锁

1.6.3 活锁

2、进程的经典调度算法

3、调度性能指标

3.1 实时监控

3.2 历史数据分析


一、操作系统概述

1、操作系统是什么

操作系统是硬件与用户及应用程序之间的媒介,向程序员提供硬件的抽象以及管理硬件资源。是一种运行在内核态的软件。

2、操作系统的核心功能

资源管理:

  • 处理器(CPU)调度:CPU的管理和分配,主要指的是进程管理。通过时间片轮转、优先级调度等算法,协调多任务运行。

  • 内存管理:内存的分配和管理,主要利⽤了虚拟内存的⽅式。分配与回收内存空间,支持虚拟内存扩展物理内存限制。

  • 设备管理(I/O管理:对输⼊/输出设备的统⼀管理。通过驱动程序控制硬件(如打印机、磁盘),处理输入/输出操作。

  • 文件系统(外存管理):管理数据存储(如NTFS、ext4),组织文件目录,控制读写权限。外存(磁盘等)的分配和管理,将外存以⽂件的形式提供出去。

用户接口:

  • 图形界面(GUI):如Windows的桌面、macOS的Finder,提供直观交互。

  • 命令行界面(CLI):如Linux的终端,支持脚本化操作。

系统服务:

  • 多任务处理:并行或并发执行多个程序。

  • 安全与权限:用户身份验证、文件访问控制(如Linux的chmod)。

  • 网络通信:管理网络协议栈(TCP/IP)、防火墙配置。

3、操作系统的内核

内核是一个计算机程序,是操作系统的核心,直接与硬件交互,负责进程调度、内存管理等底层任务。

大多数操作系统将内存分成了两个区域:

  • 内核空间,这个内存空间只有内核程序可以访问,可以访问所有的内存空间
  • ⽤户空间,这个内存空间专⻔给应⽤程序使⽤,权限⽐较⼩,只能访问一个局部的内存空间

当程序使用用户空间时,称该程序在用户态执行;当程序使用内核空间时,程序在内核态执行。

切换机制:应用程序通过系统调用(或硬件中断、或异常),此时产生一个中断,发生中断后,CPU会保存用户态的上下文(寄存器、程序计数器等),中断当前在执行的用户程序,切换模式开始执行内核程序,内核处理完后,主动触发中断,把CPU执行权限交回用户程序,恢复上下文,继续执行原程序。

二、CPU调度

1、基本概念

1.1 并行与并发的区别

并发:一段时间内,多个任务都会被处理,但在某一刻,只有一个任务在执行。通过利用时间片的轮转实现。

并行:同一时刻,有多个任务在执行。需要多核处理器才能完成,不同程序放到不同的处理器上运行。

1.2 进程与线程的区别

进程:进程是操作系统资源分配的基本单位,是程序的一次执行实例,拥有独立的内存空间和系统资源(如CPU时间、内存、文件句柄),强调隔离性和安全性。在Java中,一个运行的JVM实例通常对应一个进程,如果在程序中启动外部程序,则会创建新的子进程,与当前JVM进程独立。进程间通信需要通过特定机制(如文件、套接字、共享内存等)实现。

线程:线程是CPU调度的基本单位,是进程内的一个执行单元,线程共享进程的资源,但拥有独立的栈和程序计数器,强调执行效率和资源共享。Java中通过Thread或线程池实现多线程。线程间可以直接共享内存,但需要处理同步问题。

1.3 进程的状态

进程的五大基本状态:

状态描述
创建 (New)进程正在被创建(分配资源、初始化PCB等)。
就绪 (Ready)进程已获得除CPU外的所有资源,等待被调度(初始化完成、时间片用完或被高优先级抢占、阻塞等待事件完成)。
运行 (Running)进程正在CPU上执行指令。
阻塞/等待 (Blocked/Waiting)进程因等待外部事件(I/O完成、信号量释放、锁等)而暂停执行,主动让出CPU。
终止 (Terminated)进程执行完毕或被强制终止(如崩溃、被父进程终止),资源等待回收。

进程的状态转换:

僵尸进程:指已完成且处于终止状态,但在进程表中任然存在的进程。一般发⽣有⽗⼦关系的进程中,⼀个⼦进程的进程描述符在⼦进程退出时不会释放,只有当⽗进程通过 wait() 或 waitpid() 获取了⼦进程信息后才会释放。如果⼦进程退出,⽽⽗进程并没有调⽤wait() 或 waitpid(),那么⼦进程的进程描述符仍然保存在系统中。

孤儿进程:⼀个⽗进程退出,⽽它的⼀个或多个⼦进程还在运⾏,那么这些⼦进程将成为孤⼉进程。孤⼉进程将被init 进程 (进程 ID 为 1 的进程) 所收养,并由 init 进程对它们完成状态收集⼯作。因为孤⼉进程会被 init 进程收养,所以孤⼉进程不会对系统造成危害。

1.4 线程的状态

线程的六种状态:

状态描述
NEW(初始化)线程被创建但未启动(start()未被调用)。
RUNNABLE(就绪、运行中)线程在JVM中可运行(可能正在执行或等待CPU时间片)。READY(就绪)、RUNNING(运行中)
BLOCKED(阻塞)线程因等待监视器锁(如synchronized)被阻塞。
WAITING(等待)线程无限期等待其他线程触发条件(如Object.wait()Thread.join())。
TIMED_WAITING(等待超时)线程在有限时间内等待(如Thread.sleep(ms)或带超时的Object.wait())。
TERMINATED(终止)线程执行完毕。

线程的状态转换:

1.5 进程间通信方式

管道:是内核中的一段缓存,从管道一段写入数据,另一端读取数据

# 匿名管道(Shell中使用`|`),仅用于父子进程或有亲缘关系的进程
ls | grep "txt"

# 命名管道(创建FIFO文件),通过文件系统路径标识,允许无亲缘关系的进程通信
mkfifo my_pipe

消息队列:是保存在内核中的消息链表,进程通过发送/接收消息实现通信,消息附带类型标识。

操作接口如下:

  • msgget:创建或获取消息队列。

  • msgsnd:发送消息。

  • msgrcv:接收消息。

共享内存:多个进程映射同一块物理内存到各自的虚拟地址空间,直接读写内存实现高效通信。

操作步骤:

  1. 创建共享内存区域(shmget)。

  2. 映射到进程地址空间(shmat)。

  3. 同步访问(需结合信号量或锁)。

信号量:计数器+等待队列,用于控制多个进程对共享资源的访问(同步互斥)。保证同一时间仅一个进程使用,

操作接口

  • semget:创建信号量。

  • semop:执行PV操作(增减信号量值)

套接字:基于网络协议(TCP/UDP)或本地域(Unix Domain Socket)实现进程间通信。

示例场景

  • 跨网络通信:客户端-服务器模型。

  • 本地进程通信:Docker容器与宿主机通信。

方式适用场景优点缺点
管道父子进程简单通信简单易用单向、效率低(涉及内核态与用户态转换)
消息队列结构化数据异步传输支持消息类型、解耦生产消费消息大小受限
共享内存高频数据交换(如音视频处理)速度极快(无需内核介入)需额外同步机制(如竞态条件)
信号量进程同步与互斥灵活控制资源访问不传递数据
套接字跨网络或本地灵活通信通用性强、跨平台开销较大
信号简单事件通知(如终止进程)轻量级信息量小、不可靠可能丢失
文件映射结合文件与内存的高效访问数据持久化需处理文件锁
RPC分布式系统服务调用透明调用远程函数依赖网络、序列化开销

1.6 线程常见问题

1.6.1 死锁

死锁:在两个或者多个并发线程中,如果每个线程持有某种资源,⽽又等待其它线程释放它或它们现在保持着的资源,在未改变这种状态之前都不能向前推进,称这⼀组线程产⽣了死锁。

产生死锁的四个必要条件:

  • 互斥(Mutual Exclusion):资源一次只能被一个进程独占使用(如打印机)。

  • 占有并等待(Hold and Wait):进程持有至少一个资源,同时等待获取其他进程占有的资源。

  • 不可抢占(No Preemption):资源只能由持有者主动释放,不能被强制剥夺。

  • 循环等待(Circular Wait):存在进程间循环等待资源的链(如A等B,B等C,C等A)。

避免死锁的方法:破坏四个条件中的一个就可以

  • 破坏互斥:允许资源共享(如只读文件),但多数资源无法共享(如写操作)。

  • 破坏占有并等待:进程一次性申请所有所需资源(资源利用率低,易饥饿)。

  • 破坏不可抢占:强制剥夺资源(需恢复现场,实现复杂)。比如:占⽤部分资源的线程进⼀步申请其他资源时,如果申请不到,可以主动释放它占有的资源

  • 破坏循环等待按顺序申请资源(如统一约定锁的获取顺序)。

1.6.2 饥饿锁

饥饿锁:线程因优先级低、调度策略不合理或锁竞争激烈,长期无法获取所需资源(如锁、CPU时间),导致任务无法推进。

饥饿锁常见原因:锁策略不公平(非公平锁、线程优先级差异);资源分配算法缺陷(CPU调度策略:短作业优先、多级反馈队列);锁嵌套与竞争(线程频繁竞争同一把锁,且持有时间长);未使用超时机制。

饥饿锁解决方案:使用公平锁、动态调整优先级(老化机制、Linux的完全公平调度器)、减小锁粒度、CAS无锁编程、超时与重试机制

1.6.3 活锁

活锁:线程不断重试失败的操作,实际未阻塞但无进展(如反复让路)

活锁常见原因:过度重试机制(重试策略未引入随机性);协作策略冲突(基于对方状态动态调整);缺乏全局协调。

活锁解决方案:引入随机性(退避算法、限制重试次数);全局协调器;优先级策略;状态共享与决策同步。

2、进程的经典调度算法

(1) 先来先服务(FCFS, First-Come-First-Served)

  • 规则:按进程到达顺序分配CPU,非抢占式。

  • 优点:简单,公平直观。

  • 缺点:可能导致“护航效应”(短进程等待长进程),平均等待时间高。

  • 适用场景:早期批处理系统。

(2) 短作业优先(SJF, Shortest Job First)

  • 规则:优先执行预计运行时间最短的进程,可抢占(SJRF)或非抢占。

  • 优点:最小化平均等待时间。

  • 缺点:需预知作业时间,长进程可能“饥饿”。

  • 应用:理论最优算法,实际需结合预测(如指数平均法)。

(3) 时间片轮转(RR, Round Robin)

  • 规则:每个进程分配固定时间片(如10ms),超时后抢占并加入队列尾部。

  • 优点:公平性高,响应时间可控。

  • 缺点:时间片过长退化为FCFS,过短增加上下文切换开销。

  • 适用场景:交互式系统(如桌面操作系统)。

(4) 优先级调度(Priority Scheduling)

  • 规则:每个进程分配优先级,优先级高的优先执行,可抢占或非抢占。

  • 问题:低优先级进程可能“饥饿”;优先级动态调整(如随等待时间提升)可缓解。

  • 应用:实时系统(如航空控制系统)。

(5) 多级反馈队列(MLFQ, Multilevel Feedback Queue)

  • 混合策略

    1. 设置多个优先级队列,高优先级队列时间片短,低优先级队列时间长。

    2. 新进程进入最高优先级队列,若未在时间片内完成则降级。

    3. 定期将所有进程提升至高优先级队列,防止饥饿。

  • 优点:兼顾响应时间和吞吐量,适应不同类型任务。

  • 应用:通用操作系统(如Windows、Linux早期版本)。

(6) 完全公平调度器(Completely Fair Scheduler, CFS)

  • 规则:虚拟时间(vruntime)记录进程已运行时间,选择vruntime最小的进程执行。

              虚拟运行时间会根据进程的优先级(权重)进行加权调整,优先级高的进程(如实时任务)vruntime 增长更慢,从而更快被调度器选中。

                 调度器尝试在一个周期内让所有可运行进程至少运行一次。

                 所有可运行进程按 vruntime 从小到大排序,存储在一棵红黑树中,每次选择vruntime 最小的进程(即最左侧节点)执行,确保调度复杂度为O(log n)

  • 应用:Linux操作系统。

3、调度性能指标

3.1 实时监控

CPU使用率

  • 用户态时间(us):CPU执行用户进程的时间占比,过高可能表示应用负载重。优化应用代码或增加CPU核心。

  • 内核态时间(sy):CPU处理系统调用的时间,过高可能表明I/O或内核操作频繁。检查内核模块或I/O子系统(如磁盘/网络)。

  • 等待I/O时间(wa):CPU等待磁盘I/O完成的时间,高值提示I/O瓶颈。优化磁盘I/O(如使用SSD、调整RAID)。

  • 空闲时间(id):CPU未被使用的时间占比。

  • 中断时间(hi/si):硬件中断(hi)和软中断(si)处理时间,高值可能由网络或外设问题引发。

平均负载(Load Average):

  • 过去1、5、15分钟内的平均活跃任务数(包括运行中和不可中断的任务)。

  • 理想值:不超过CPU逻辑核心数。例如,8核系统负载长期超过8需关注。

  • 高平均负载但低CPU使用率:检查I/O等待(wa)或不可中断进程(如磁盘密集型任务)

top   # 综合查看CPU、内存、进程状态

关键字段

  • %Cpu(s):显示us/sy/ni/id/wa等时间占比。

  • Tasks:运行(running)、阻塞(blocked)的进程数。

  • Load average:平均负载。

mpstat -P ALL 1  # 显示所有CPU核心的实时数据,查看多核CPU的详细利用率

运行队列长度:

  • 等待CPU执行的进程/线程数量,若持续超过CPU核心数的2倍,可能表示CPU资源不足

上下文切换:

  • 进程或线程切换时,CPU需要保存和恢复上下文环境,频繁切换会导致性能下降。减少线程竞争(如锁优化),调整进程优先级(nice/renice)。

  • 主动切换(cswch/s):进程主动让出CPU(如等待资源)。

  • 被动切换(nvcswch/s):CPU时间片耗尽后被强制切换。

中断频率:

  • 硬件中断(如网卡数据包到达)和软中断(如定时任务)的频率,高中断可能影响调度效率。

  • 中断频繁:优化网卡配置(如多队列、中断绑定),检查硬件故障(如损坏的网线)

vmstat 1  # 每秒刷新一次,分析虚拟内存、CPU、进程队列及上下文切换

关键字段

  • r:运行队列长度。

  • cs:每秒上下文切换次数。

  • in:每秒中断次数。

pidstat -w -t -p <PID> 1  # 查看线程级上下文切换,监控特定进程的调度行为
cat /proc/interrupts  # 查看各CPU核心的中断分布

调度延迟:

  • 进程从就绪状态到实际获得CPU的时间,高延迟可能因CPU竞争激烈或调度策略不当。

perf sched record  # 记录调度事件
perf sched latency  # 分析调度延迟

3.2 历史数据分析

sar -q  # 查看历史运行队列和负载
sar -w  # 查看历史上下文切换

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值