操作系统相关的一些问题总结

进程优先级调度

什么是进程优先级调度?

简单说,OS 会给每个进程分配一个 "优先级数值",调度器每次选 CPU 时,优先挑优先级最高的就绪进程运行。比如我们电脑里的杀毒软件后台扫描(低优先级),不会打断正在打字的编辑器(中优先级);而系统的内存管理进程(高优先级),哪怕编辑器在运行,也能优先占用 CPU 处理关键任务 ------ 这就是优先级调度的核心目的:资源向核心任务倾斜,平衡 "响应速度" 和 "资源利用率"

动态、静态优先级是什么?

  • 静态优先级:进程创建时就定好,后续基本不变(比如程序员通过nice命令设置,或系统默认分配)。比如 Linux 里nice值范围是 -20~19值越小,优先级越高-------20 是最高,19 是最低

  • 动态优先级:进程运行中,OS 根据行为动态调整。比如:

    • IO 密集型进程(比如浏览器、数据库,经常等磁盘 / 网络):OS 会提高优先级,因为它 "占着 CPU 的时间短",多给机会能让用户感觉更流畅;

    • CPU 密集型进程(比如视频渲染、数学计算,一直占 CPU):OS 会降低优先级,避免它独占 CPU,导致其他进程卡壳。

什么是两种调度策略?

  • 抢占式:高优先级进程就绪后,能直接 "打断" 正在运行的低优先级进程,抢占 CPU。比如你正在用播放器(中优先级),突然系统弹出杀毒提醒(高优先级)------ 播放器会暂时暂停,让提醒先显示,这就是抢占式的好处:关键任务响应快

  • 非抢占式:低优先级进程没跑完之前,高优先级进程只能等着,不能打断。现在很少用,缺点很明显:如果低优先级进程卡死,高优先级进程也没法运行。

什么时候换进程?

  • 进程主动放弃 CPU(比如调用sleep、等待 IO 完成);

  • 进程时间片用完(哪怕优先级高,也不能一直占着,比如 Linux 里高优先级进程时间片更长,但还是会轮换);

  • 新的高优先级进程就绪(比如刚创建的系统进程,或之前等待 IO 的高优先级进程完成等待);

  • 发生中断(比如键盘输入、网络数据到达)

常见的调度器

一、O(N)调度器

what?

这是最早期的调度器,它通过遍历整个就绪队列来寻找优先级最高的进程,时间复杂度是 O (N)

1、核心
  • 系统维护一个按优先级排序的链表数组,每个优先级对应一个链表。

  • 调度时,从最高优先级开始,逐个遍历链表,找到第一个可运行的进程。

  • 进程运行时,会消耗时间片,时间片用完后被移到低优先级队列或重新计算优先级

2、特点
  • 优点:实现简单,逻辑直观。

  • 缺点

    • 当就绪进程数量多时,遍历开销大,调度延迟高(比如几百个进程时,遍历要花不少时间)。

    • 高优先级进程可能长期霸占 CPU,导致低优先级进程 "饥饿"

二、O(1)调度器

what?

为解决 O (N) 的遍历开销而生,调度决策的时间复杂度是 O (1),不随就绪进程数量变化

1、核心
  • 双数组结构

    • active 数组:存放当前有时间片的进程,按优先级分组。

    • expired 数组:存放时间片用完的进程。

  • 位图索引:用一个位图(bitmask)记录哪些优先级有可运行进程,调度时通过位图快速定位最高优先级(位运算直接找第一个置1的位)。

  • 时间片分配 :高优先级进程时间片长,低优先级短,用完后移到 expired 数组,当 active 为空时,交换两个数组

2、特点
  • 优点:调度速度快,无论多少进程,找最高优先级进程都是 O (1) 操作。

  • 缺点

    • 对交互式进程优化不足(比如 IO 密集型进程可能因时间片用完被打入低优先级)。

    • 优先级数量有限(比如 256 个),灵活性不够

三、时钟中断

what?

调度器的 "触发器",通过硬件时钟定期触发调度,保证系统公平性和及时性

1、核心
  • 硬件时钟每 10ms ~ 100ms 产生一次中断(时钟节拍)。

  • 中断发生时,内核会:

    1. 更新系统时间。

    2. 减少当前进程的时间片,时间片为 0 时标记为 "需要重新调度"。

    3. 检查是否有更高优先级进程就绪,若有则触发抢占。

    4. 定期进行负载均衡(比如把进程从繁忙 CPU 移到空闲 CPU)

2、作用
  • 避免进程无限占用 CPU,保证时间片轮转。

  • 及时响应高优先级进程,实现抢占式调度。

  • 维护系统时间和进程运行统计信息

四、CFS(完全公平调度器)

what?

目前 Linux 默认调度器,基于 "完全公平" 思想,用虚拟运行时间(vruntime) 替代固定时间片,时间复杂度 O (logN)

1、核心
  • vruntime :进程的 "虚拟运行时间",计算公式为 实际运行时间 × (1024 / 进程权重)。优先级越高,权重越大,vruntime 增长越慢。

  • 红黑树:所有就绪进程按 vruntime 排序存入红黑树,调度时取树中 vruntime 最小的进程(最 "饥饿" 的进程)。

  • 时间片动态调整:没有固定时间片,进程运行一段时间后,若 vruntime 超过其他进程,会被抢占。

  • 交互式优化:IO 密集型进程(如键盘输入、鼠标操作)因经常睡眠,vruntime 增长慢,会被优先调度,保证响应速度

2、特点
  • 公平性好,每个进程获得的 CPU 时间与优先级成正比。
  • 对交互式进程友好,响应速度快。

  • 支持动态优先级调整,适应不同负载场景

五、总结

O (N)(简单但低效)→ O (1)(高效但不够灵活)→ CFS(公平且灵活) ,而时钟中断调度是所有调度器的基础触发机制

早期 Linux 用 O (N) 调度,遍历队列找进程,简单但进程多了就卡;后来升级到 O (1),用位图快速定位优先级,解决了遍历开销;现在主流是 CFS,用 vruntime 和红黑树实现完全公平,还优化了交互式体验;而这一切都离不开时钟中断,它定期触发调度,保证系统能及时切换进程,不卡顿

软硬链接

一、硬链接

what?

给文件的 inode 起一个新的文件名映射,多个硬链接指向同一个 inode,本质是 "同一个文件的不同名字",就像引用一样,是不独立的

实现

  • 在对应文件中将对应的inode编号所对应的文件名个数加一,ls命令可以展示count,同时加一个该inode与文件名的对应关系

  • 硬链接的创建:ln 原文件 硬链接文件 本质是 ------ 在目录的 data block 中,新增一条 "硬链接文件名→原文件 inode 编号" 的目录项

  • 关键细节(类比引用):

    • 原文件和硬链接文件的 inode 编号完全相同;

    • inode 中的 "链接计数(link count)" 会 + 1(比如原文件 link count=1,创建一个硬链接后变成 2);

    • 数据块和元数据(权限、大小、修改时间等)完全共享,修改任何一个,其他硬链接都会同步变化

二、软链接

what?

创建一个独立的新文件,该文件的 inode 数据块中存储的是 "原文件的路径",访问软链接时,系统会自动跳转去访问原文件,原文件与链接文件是相互独立的

实现

  • 软链接的创建:ln -s 原文件 软链接文件 本质是 ------ 创建一个全新的 inode(有独立的 inode 编号),该 inode 的 data block 中只存储 "原文件的绝对 / 相对路径"(比如/home/user/test.txt

  • 关键细节:

    • 软链接文件有自己独立的 inode,link count 始终为 1;

    • 软链接的文件类型标识为l(用ls -l查看时,首字符是l);

    • 访问软链接时,系统会先读取其 data block 中的路径,再根据路径去查找原文件的 inode,最终访问原文件的数据

三、对比

对比维度 硬链接(Hard Link) 软链接(Soft link)
inode 编号 与原文件完全相同(共享 inode) 有独立的 inode 编号(独立文件)
链接计数(link count) 原文件和硬链接的 link count 同步增减 软链接自身 link count 始终为 1
存储内容 无独立存储,共享原文件的数据块和数据 独立数据块,存储原文件的路径(绝对 / 相对)
原文件删除后 不影响,其他硬链接仍可正常访问(link count-1) 软链接失效(变成 "断链",ls 查看呈红色闪烁)
跨文件系统(如 ext4→NTFS) 不支持(inode 编号仅在当前文件系统内唯一) 支持(仅存储路径,与文件系统无关)
指向对象 仅能指向文件,不能指向目录 可指向文件或目录
路径类型 仅支持相对路径(基于当前目录) 支持绝对路径和相对路径
文件类型标识(ls -l) 与原文件一致(如-表示普通文件,d表示目录) 单独标识为l(link)
权限设置 与原文件共享权限(设置硬链接权限会同步影响原文件) 自身权限为rwxrwxrwx(但实际访问权限由原文件决定)

四、小问题

1. 为什么硬链接不能指向目录?

  • 核心原因:会导致目录树循环

  • 补充:目录的默认 link count 是 2(自身目录项 + 父目录的..指向),如果允许硬链接目录,会破坏目录树的层级结构和 link count 的计算逻辑。

2. 软链接的权限为什么是rwxrwxrwx?实际访问时以什么为准?

  • 表面权限是777,但这是 "假权限",实际访问软链接时,系统会穿透到原文件,以原文件的权限为准;

  • 比如软链接link.txt权限是rwxrwxrwx,但原文件test.txt权限是rw-r--r--,则普通用户只能读取link.txt,不能修改

  • link count 为 0 表示没有任何文件名指向该 inode,系统会回收该 inode 及其对应的数据块,文件彻底删除

4. 软链接变成 "断链" 的常见原因?

  • 原文件被删除或移动到其他路径

  • 软链接使用相对路径,且软链接文件被移动到其他目录(比如在/home创建ln -s test.txt link.txt,再把link.txt移到/root,访问时会找/root/test.txt,而原文件在/home

软硬链接的核心区别在于是否共享 inode:硬链接是文件的别名,共享 inode 和数据,删除原文件不影响,不能跨文件系统、不能指向目录;软链接是独立文件,存储原文件路径,原文件删除后失效,支持跨文件系统和目录

僵尸进程

what?

僵尸进程是已经终止运行,但父进程未处理其返回信息的进程

僵尸进程的危害

  • 进程进入僵尸状态之后,如果父进程一直不做处理,那么操作系统就要一直维护僵尸进程的退出信息,占用了CPU资源

  • 同时,内存中还要一直维护进程的PCB进程信息控制块,如果一直不做处理的话,PCB的内存将会泄漏

  • 进程pid是有限的,如果有大量的pid被僵尸进程占用,就不能创建新进程了

僵尸进程的处理

  1. 父进程调用wait()/waitpid(),回收子进程的退出信息

  2. 杀死父进程

为什么kill无法杀死僵尸进程?

  • 核心:僵尸进程已经终止运行,不再执行任何代码,kill信号的作用是 "通知进程执行特定操作"(如终止、暂停),但对已终止的进程无效;

  • 僵尸进程的残留是 "PCB 未回收",而非 "进程仍在运行",所以只能通过回收 PCB 的方式清除,不能用kill

相关推荐
智慧地球(AI·Earth)15 小时前
在Linux上使用Claude Code 并使用本地VS Code SSH远程访问的完整指南
linux·ssh·ai编程
世转神风-16 小时前
qt-kits-警告:No C++ compiler,无法正常解析工程项目.pro文件
开发语言·c++
翔云 OCR API16 小时前
承兑汇票识别接口技术解析与应用实践
开发语言·人工智能·python·计算机视觉·ocr
元周民16 小时前
matlab求两个具有共根的多项式的所有共根(未详细验证)
开发语言·matlab
老王熬夜敲代码16 小时前
解决IP不够用的问题
linux·网络·笔记
zly350017 小时前
linux查看正在运行的nginx的当前工作目录(webroot)
linux·运维·nginx
不忘不弃17 小时前
十进制数转换为二进制数
开发语言
QT 小鲜肉17 小时前
【Linux命令大全】001.文件管理之file命令(实操篇)
linux·运维·前端·网络·chrome·笔记
csbysj202017 小时前
jQuery Mobile 触摸事件
开发语言
代码村新手17 小时前
C++-入门
开发语言·c++