操作系统核心:进程描述与控制,从概念到Linux实践

发布时间:2026/9/29 1:58:40
操作系统核心:进程描述与控制,从概念到Linux实践 “操作系统”这四个字几乎每个计算机专业的学生都在课表上见过但真正学明白的人不多。最近我重新翻完了《计算机操作系统慕课版》第一章和第二章最大的感受是如果只看定义、背概念那你永远在门外如果能把“操作系统”当成一个真实存在的系统来理解把“进程”当成一个活生生的对象来观察这两章其实非常生动。这篇笔记我就按自己的学习顺序来写先聊操作系统为什么存在、它到底管了哪些事再重点拆解进程的描述与控制最后补充一些我用Linux命令验证概念的方法。无论你是正在期末复习还是刚开课想提前踩点这篇内容都能帮你把书读薄。1. 先搞懂“Why”再去看“What”操作系统存在的唯一理由1.1 没有操作系统的裸机到底有多难用我见过不少同学一上来就背“操作系统是管理计算机硬件与软件资源的系统软件”背是会背但根本不理解这句话的分量。换个角度想如果一台电脑没有操作系统只有CPU、内存、磁盘这些硬件你想运行一个程序该怎么办你得自己把程序从磁盘搬到内存自己设置CPU寄存器自己处理键盘鼠标的中断自己想办法让打印机把结果吐出来。一个程序还好如果同时有两个程序呢谁先运行内存怎么分配一个程序崩溃了会不会把另一个程序的数据也踩掉这些问题靠程序员自己在每个应用里解决成本高到不可想象。操作系统存在的第一个理由就是把“公共的、底层的、容易出乱子的事”统一收走让应用程序只关心自己的业务逻辑。这里可以打一个简单的比方操作系统就像一个公司的行政后勤部门。研发人员应用程序不需要自己修水电、管门禁、订办公用品这些事由行政统一负责行政管得好整栋楼的人都能安心干活行政一崩所有人都得停摆。1.2 操作系统的三层角色管家、调度员、翻译官把操作系统的职责拆成三个角色去记第一章就会变得非常清晰。第一层是资源管家。CPU、内存、设备、文件这四大资源全归操作系统管。管的核心原则就两条一是安全不能让一个进程随便读写另一个进程的内存二是公平不能让一个程序饿死其他程序。后面学到的银行家算法、时间片轮转、虚拟内存本质上都是在落实这两条原则。第二层是调度员。程序什么时候运行、运行多久、跑到一半被谁打断这些决策都由操作系统来做。调度员的能力直接决定系统“卡不卡”“快不快”。比如你一边写文档一边放音乐如果操作系统把CPU长时间分给文档程序音乐就会断续你立刻会怀疑电脑坏了。第三层是翻译官。用户和应用程序通过系统调用向操作系统提出请求操作系统把请求翻译成硬件能听懂的指令。你在代码里写一句read(fd, buf, 1024)背后其实是用户态到内核态的切换是一长串硬件寄存器的操作。这些细节应用开发者不需要关心这正是操作系统“翻译”的价值。1.3 系统调用用户接触操作系统的唯一正门说到系统调用这是第一章里容易被忽略但极其重要的知识点。很多教材会列出一大堆系统调用的例子比如进程控制类的fork()、exec()文件操作类的open()、read()、write()设备管理类的ioctl()。你不需要全背但要理解一个核心思想应用程序想要碰硬件必须通过系统调用这扇门没有第二条路。为什么必须这样因为如果每个程序都能直接操作硬件那么一个bug就能搞垮整台机器。操作系统把硬件操作封装成一个个“服务窗口”你有需求就来排队申请操作系统检查你的权限、分配资源、执行操作、返回结果。printf之所以能在屏幕上输出文字底层就是调用了write这个系统调用你在学习时可以用strace命令去查看一个程序的真实行为比如strace -f ls会看到一长串系统调用那一刻你会觉得操作系统变得特别具体。2. 第一章的精髓并发、共享、虚拟、异步到底在说什么2.1 并发不等于并行一字之差天壤之别大多数教材把并发和共享列为操作系统的两个基本特征而“并发”是我见过学生理解偏差最大的词。并发Concurrent是指两个或多个事件在同一个时间间隔内发生宏观上看起来是同时发生的微观上其实是交替执行的。单核CPU上就是典型的并发——操作系统快速地在多个进程之间切换运行每个进程跑一小会儿就被换下去因为切换速度快用户感觉所有程序都在同时跑。并行Parallel是指两个或多个事件在同一个时刻真正同时发生这要求系统有多个CPU核心。多核处理器上不同核心可以真正并行执行不同的进程。考试爱考这个区别面试也爱问。你可以这样记并发是“一个人同时干几件事”本质是切换并行是“几个人同时各干一件事”本质是同时。Go语言里的Goroutine天然支持并发但能不能并行要看机器有没有多核这就是很多人调优时忽略的问题。2.2 共享的两种方式互斥共享和同时共享共享是指系统中的资源可供多个并发执行的进程共同使用。但资源分两种性格处理方式完全不同。一种是互斥共享比如打印机、磁带机这类设备。同一时刻只允许一个进程访问其他进程必须等。要是两个进程同时往打印机输出打出来的文档就会互相穿插谁也看不懂。操作系统会用锁、信号量这类机制来保证互斥这也是第二章之后会重点学的同步问题来源。另一种是同时共享比如磁盘、内存。这里的“同时”也是宏观上的微观上还是分时交替。你一边下载文件一边浏览网页两个进程感觉都在用磁盘实际上是操作系统把磁盘访问切碎了分给它们。这里要记住一句话并发和共享互为存在条件。如果没有并发一次只运行一个程序资源不需要共享如果没有共享每个程序独占所有资源也无法实现并发。考试如果出简答题问“为什么说并发和共享是操作系统的两个基本特征”你就围绕这句话展开。2.3 虚拟让你的4G内存跑出8G的效果虚拟这个特征最反直觉。操作系统用虚拟技术把物理资源变成逻辑上的“假资源”。最典型的就是虚拟内存你的物理内存只有4G但每个进程都觉得自己的地址空间有4G甚至更大。程序访问某个地址时操作系统通过页表把这个逻辑地址映射到物理地址如果发现这块数据不在内存里就从磁盘换入。这就是所谓“虚拟”的含义——用户看到的是一个比物理资源大得多的逻辑空间。虚拟技术还有另一面虚拟处理器。你只有一个CPU但操作系统把它虚拟成无数个逻辑CPU每个进程都觉得自己独占了一个CPU在跑。这就是分时共享的底层逻辑。学这块时我推荐一个理解方法把虚拟当成一层“障眼法”。操作系统是那个变魔术的人应用程序是观众观众只看到魔术效果不需要知道道具怎么藏的。2.4 异步不死记用生活中的“排队”来理解异步是指进程以不可预知的速度向前推进。你今天跑一个程序它可能10秒结束明天同样的输入可能花了11秒因为系统里的进程调度顺序、中断时机每次都不一样。初学者最容易焦虑的就是“为什么程序运行时间不稳定”其实这正是操作系统异步性的表现。进程在执行过程中可能随时被操作系统暂停去执行另一个进程什么时候恢复自己说了不算。这种不可预测性是操作系统多道程序设计带来的自然结果不是bug。理解异步的关键是接受“不确定性才是常态”。现实中你用手机App网络请求什么时候返回也不确定但用户已经习惯了加载中的状态。操作系统也一样它保证每个进程最终都能推进但不保证它什么时候推进这就是异步的温柔。3. 拆解操作系统的四大功能处理机、内存、设备、文件3.1 处理机管理把CPU时间切好分给你处理机管理说白了就是进程管理和调度。操作系统的CPU管理不是自己用CPU而是决定“谁用CPU、用多久”。这一部分在第二章会详细展开第一章只需要知道处理机管理包含进程控制、进程同步、进程通信和调度几个模块。调度器需要回答三个问题选哪个进程运行多久什么时候切换这三个问题对应不同的调度算法比如先来先服务FCFS、短作业优先SJF、时间片轮转RR、多级反馈队列MLFQ。第一章只是引子学完整个课程再回头看你会发现所有调度算法都围绕三个指标展开吞吐量、周转时间、响应时间。3.2 存储器管理分配地址也保护地址存储器管理管的是内存。它要做的事包括为每个进程分配内存空间、通过页表或段表把逻辑地址转换成物理地址、在内存不足时把部分数据换到磁盘上、保护一个进程的内存不被其他进程非法访问。我学这一块时最大的误区是把内存管理理解成“只要给进程分配一块区域就行”。实际远不止操作系统必须解决碎片问题、共享问题、重定位问题。比如一个进程的内存空间不够了能不能扩展程序被换到磁盘再换回来地址变了怎么办这些都是第一章先抛出问题、后续章节给答案的内容。学习建议别纠结细节先建立“内存管理 分配 映射 保护 扩充”这个框架后面的分页、分段、虚拟内存都是围绕这个框架填肉。3.3 设备管理让不同设备看起来一样“听话”设备管理处理I/O相关的所有事情。操作系统为每一种设备提供统一的接口应用程序只需要调用read、write不需要关心设备是机械硬盘还是SSD是USB摄像头还是网卡。设备管理的另一个核心任务是缓冲和中断处理。CPU的速度远快于设备如果把CPU一直等着慢速设备浪费巨大。所以操作系统用缓冲区暂存数据用中断机制在设备准备好时再通知CPU处理。你在键盘上每敲一个字母都会触发一次键盘中断CPU停下手中的活去读这个字符然后再回来继续之前的任务。可以用一个场景来理解你在餐厅点餐服务员CPU不会站在厨房门口等菜设备而是去服务别的客人菜好了厨房喊一声中断服务员再过去上菜。这样餐厅的吞吐量才能上去。3.4 文件管理把磁盘数据抽象成树形目录文件管理的本质是把磁盘上零散的存储块组织成用户方便理解的“文件”再通过目录结构把这些文件组织成树形。删除文件时你感觉是“删了一个文件”实际上操作系统做的是回收磁盘块、更新目录项、清除inode信息——对机械硬盘来说还要清空位图对应位置。第一章讲到文件系统时很多小白会问“为什么不直接按文件名找数据”答案是磁盘的物理特性决定它最适合按块读写而不是按“文件名”读写。文件系统就是在“物理块”和“逻辑文件”之间架桥的模块这个桥架得好不好直接决定你复制一个大文件是10秒还是1分钟。4. 第二章开篇进程是怎么被“逼”出来的4.1 从程序的顺序执行到并发执行第二章一开始就在铺垫一个背景程序为什么要“并发执行”答案很现实——提高资源利用率。一个程序在等待I/O时CPU完全可以在另一个程序上工作否则CPU大部分时间都在“摸鱼”。但并发执行带来了问题程序之间的执行顺序不再固定计算结果可能受执行速度的影响。教材里用前驱图来描述程序各部分的先后约束关系用“Bernstein条件”来判断两个程序是否可以并发执行且结果不变。这块不需要钻太深但要理解一个核心转变并发执行的程序已经不再是一个“程序”了它变成了一个“过程”、一个“活动”而这个活动的实时状态就是进程。程序是静态的躺在磁盘上进程是动态的活在内存中。这就是为什么要发明“进程”这个概念——为了描述并发执行中不断变化的程序活动。4.2 前驱图画清楚“谁先谁后”前驱图是一个有向无环图节点代表程序段或语句箭头代表前驱关系。比如S1 - S2表示S1必须在S2之前执行。这个概念不难但它是理解并发的基础。你可以把前驱图想象成做饭的流程洗菜、切菜、炒菜。切菜必须等洗菜完成炒菜必须等切菜完成但有三个菜可以同时洗、同时切吗在某些条件下可以并行进行。前驱图能帮你看出哪些步骤彼此独立、可以并发哪些步骤有依赖、必须串行。考试喜欢让你根据前驱图判断并发执行的条件所以一定要会画、会读。一个技巧只要两个节点之间没有路径相连它们就可以并发执行有路径相连的必须按路径顺序来。4.3 进程的教科书定义以及为什么不是“运行中的程序”这么简单教材对进程的定义是“程序关于某个数据集合的一次执行过程”。很多人把它简化成“运行中的程序”这个简化理解在大多数场合够用但一到考试和面试就容易翻车。为什么不能简单说“运行中的程序”因为进程包含的信息远多于程序本身。它不只是代码还包括当前执行到的位置程序计数器、上下文数据、打开的文件、分配的内存、进程优先级……这些信息合在一起才构成一个完整的“执行过程”。如果用一句话描述进程我会说进程是操作系统为了管理程序的并发执行而引入的一个实体它是资源分配和调度的基本单位。后半句特别重要——进程是“资源分配和调度的基本单位”这意味着CPU时间、内存空间、文件句柄都记在进程头上。后面学到线程时会对比线程是“调度的基本单位”但线程不拥有资源它隶属于进程这就是区别所在。4.4 进程和程序五个维度看清差别我整理过一张对比表期末考试和面试前都靠它速记对比维度程序进程状态静态是文件动态是执行过程生命周期永久存在除非删除文件从创建到终止有生有死组成指令和数据程序、数据、PCB进程控制块对应关系一个程序可对应多个进程一个进程只能对应一个程序并发性自身无并发性多个进程可并发执行这里“一个程序可对应多个进程”值得展开。你双击同一个可执行文件三次系统里会出现三个进程它们执行的是同一份代码但各自有独立的内存空间和数据。用ps -ef | grep firefox能看到多个firefox进程就是这个道理。5. PCB进程在操作系统眼中的“身份证”5.1 PCB里到底装了什么进程控制块Process Control BlockPCB是操作系统中最重要的数据结构之一。操作系统不认识“进程”这种抽象概念它只认识PCB——一个包含进程全部管理信息的数据结构。可以说PCB是进程存在的唯一标志进程创建时操作系统为它分配一个PCB进程结束时回收PCBPCB没了进程就“死”了。PCB里的信息可以分成四类第一类是进程标识符包括进程号PID和父进程号PPID。ps -l命令第一列看到的PID就是进程在系统里的“身份证号”。第二类是处理机状态信息包括通用寄存器值、程序计数器PC、程序状态字PSW。这些信息的作用是支持进程切换。当一个进程被暂停时它的CPU现场被存到PCB里等它再次被调度时再从PCB恢复现场继续运行。这就是“上下文切换”的物理基础。第三类是进程调度信息包括进程状态就绪、运行、阻塞、优先级、等待事件等。调度器就是靠这些信息来决定“下一个该运行谁”。第四类是进程控制信息包括程序和数据的地址、进程同步和通信机制、资源清单等。这些信息用于进程的管理和资源回收。你可以把PCB理解成“病历本”病人进程的病历本上记录着他的各项指标医生操作系统不直接看病人只看病历本就大概知道该怎么处理。同样操作系统每次切换进程本质上是切换了PCB指针。5.2 创建和终止一个进程操作系统做了什么进程的生命周期管理是第二章的重点。用fork()在Linux里创建进程是最典型的例子它的行为很奇特调用一次返回两次。父进程收到子进程的PID子进程收到0。如果是负数则是创建失败。fork()底层做的事包括分配新的PCB、复制父进程的地址空间、初始化各种资源、把子进程加入就绪队列。注意这里是“复制”子进程获得的是父进程的一个副本所以父子进程从fork()返回的那一刻起各自拥有独立的地址空间互不影响。这就是“进程隔离”的起点。终止一个进程也有一套流程。无论是正常退出return 0、错误退出exit(-1)还是被信号杀死kill -9操作系统都会回收该进程占用的资源并从系统进程表中删除它的PCB。我大学时踩过一个坑用while(1) fork();写了个病毒演示程序瞬间把系统进程表塞满电脑直接卡死。当时不理解为什么系统不阻止我后来才知道创建进程前系统会检查进程数上限但短时间内爆发式创建还是会让系统设计师“措手不及”。现在生产环境的容器编排系统会限制容器内进程数也是同样的道理。5.3 空进程到底是什么很多人搜过“什么叫空进程”这个概念让不少初学者困惑。其实空进程在不同语境下含义不同。在Windows的任务管理器里有时会看到一个进程叫“System Idle Process”系统空闲进程CPU占用率经常显示为90%以上。它不干实事它的任务是在CPU没有其他可运行的进程时占据CPU时间让CPU进入低功耗的空转状态。你看到“空闲进程占用CPU高”恰恰说明系统很闲。在Linux下同样有类似机制核心是0号进程swapper/idle系统没有活干时就会跑它。理解空进程的意义在于消除恐慌它不是病毒不是挖矿程序而是操作系统”保持系统不崩溃”的保底机制。以后你看到某个进程叫idle或显示CPU占用高但电脑不卡先别急着杀查清楚再动手。6. 进程状态的完整生命周期从生到死从就绪到阻塞6.1 三状态模型就绪、运行、阻塞进程状态转换是第二章必考内容几乎每个学校期末都会出。最经典的三状态模型包括就绪态进程万事俱备只欠CPU。它已经获得除CPU外的所有资源只要调度器把CPU分给它立刻就能运行。系统里通常有多个进程处于就绪态排成就绪队列。运行态进程正占用CPU执行指令。在单核CPU上任意时刻只有一个进程处于运行态。阻塞态进程因为等待某事件而暂停执行比如等待用户输入、等待磁盘I/O完成。阻塞态的进程即使给它CPU也跑不了因为它等的事还没发生。状态转换的规则是考试的得分点我建议你记住五个字的口诀“等、抢、睡、醒、终”就绪 - 运行调度器选中它这叫“抢”到CPU。运行 - 就绪时间片用完或更高优先级进程到达被“踢”回就绪队列。运行 - 阻塞进程自己请求等待某事件比如read阻塞在键盘输入上这叫“睡”下了。阻塞 - 就绪等待的事件完成进程被唤醒重新进入就绪队列这叫“醒”了。运行 - 终止进程执行完毕或被强制结束走上“终”点。我见过不少同学在“运行-就绪”这一步犯迷糊总觉得“运行得好好的为什么要退回去”。原因是操作系统需要保证公平不能让一个进程独占CPU太久。比如一个进程连续跑了几百个时间片调度器就会把它换下去让其他进程也有机会运行。这是多道程序设计的基本要求。6.2 挂起给进程“冬眠”的机会三状态模型之上很多教材会拓展到五状态或七状态模型新增了“挂起态”静止态。挂起和阻塞有什么区别阻塞是自己“主动”睡眠等待某个事件挂起是外部“被动”冻结比如用户按下暂停键、系统内存紧张把进程换到磁盘、调试器单步暂停。挂起态的进程不参与CPU调度它在等待一个外部动作如恢复操作来结束挂起而不像阻塞态是等待I/O事件完成。挂起可以发生在就绪进程上静止就绪也可以发生在阻塞进程上静止阻塞。这个知识点对日常开发有一个非常实际的意义当你用CtrlZ把前台进程挂起再用bg把它放到后台继续你其实是在跟操作系统的挂起机制打交道。用jobs命令能看到任务状态其中Stopped就是挂起态。6.3 用Linux命令亲眼看看进程状态光看书容易晕我建议你打开终端同步验证。下面是我验证进程状态时常用的几个命令# 查看所有进程的PID、状态、父进程等信息 ps -l # 动态刷新进程状态按CPU使用率排序 top # 查看进程树 pstree # 把进程放到后台运行 sleep 300 # 查看后台任务 jobs # 把后台任务恢复到前台 fgps -l输出中的STAT列就是进程状态常见的有RRunning运行中、SSleeping可中断睡眠、D不可中断睡眠通常是在等磁盘I/O、ZZombie僵尸进程、TStopped停止/挂起。我特别喜欢拿sleep 300做实验先让它跑着用ps看到状态是S然后CtrlZ挂起它再用ps看状态变成T。这样你就从“肉眼”上看到了进程状态的切换比死记“挂起态必须由外力激活”形象得多。6.4 僵尸进程一个值得单独讨论的“尸体”ps输出里的Z状态僵尸进程值得单独拿出来说。当一个子进程终止后如果父进程没有调用wait()回收它的退出状态子进程的PCB不能被完全释放它就变成了僵尸进程。它不占用CPU、也不占用内存除了PCB本身但会占据进程表中的一个位置。如果你写了一个服务程序父进程负责创建子进程但忘了回收长期运行后会出现一堆僵尸进程最终可能导致无法创建新进程。排查办法很简单用ps aux | awk $8Z看看哪些进程处于Z状态然后去代码里检查是否调用了wait()或waitpid()。这个知识点在考试中常以“僵尸进程产生的原因”出现但在真实开发里它是一个真实存在的坑。我在一次线上事故排查中遇到过某网关程序因为忘记回收子进程跑了一星期后进程数达到上限新请求全部失败重启服务才恢复。从那以后我养成了一个习惯服务端代码里只要有子进程必须同时写好回收逻辑。7. 线程进程的“轻量级分身”是怎么来的7.1 为什么不能只有进程第二章后半部分讲线程它的引入逻辑其实是被“逼”出来的。进程有两个基本属性资源分配和调度执行。但这两个属性捆在一起有一个问题调度切换的开销太大。进程切换要把CPU现场完整存到PCB里再加载新进程的现场还要切换地址空间、更新页表这个过程叫“上下文切换”。上下文切换本身不产生任何业务价值纯粹是管理成本。如果程序内部需要频繁协调多个任务比如一个下载工具要同时处理下载、界面刷新、日志记录用多个进程来实现切换成本实在太高而且进程之间的内存相互隔离想共享数据还得通过IPC机制开发效率也很低。于是一个自然的想法出现了能不能把“调度”和“资源”两个属性分离让进程继续拥有资源创建一个更轻量的实体来负责调度执行这就是线程。线程共享进程的地址空间和资源但每个线程有自己独立的程序计数器、寄存器和栈。进程是“资源分配单位”线程是“调度单位”这句话请大家务必记住。7.2 进程和线程的对比别再傻傻分不清我整理了一个精简版对比面试时百试百灵对比维度进程线程资源拥有拥有独立地址空间和资源共享所属进程的资源调度单位早期系统以进程为调度单位现代OS以线程为调度单位独立调度切换开销大需切换地址空间小只切换现场通信方式需要IPC管道、消息队列、共享内存等可直接读写共享内存但需要同步机制健壮性一个进程崩溃一般不影响其它进程一个线程崩溃可能拖垮整个进程创建开销大小结合日常经验理解Chrome浏览器为每个标签页开一个进程好处是某个页面崩溃不会连累其他页面而大多数服务端程序用多线程模型好处是切换快、节省内存但一个线程出现野指针就可能让整个服务core dump。7.3 用户级线程和内核级线程一个必须知道的两难教材在这块通常会介绍两种线程实现方式以及它们的组合模型。**用户级线程ULT**在用户空间实现内核完全不知道线程的存在内核只看到进程。线程的调度由用户空间的线程库完成优点是切换不涉及内核速度极快缺点是一个线程发起系统调用阻塞时整个进程的所有线程都会被阻塞而且多核CPU无法真正并行调度多个用户级线程。**内核级线程KLT**由内核管理线程创建、调度、销毁都由内核完成。优点是多核可以利用起来一个线程阻塞不影响同进程的其他线程缺点是线程切换需要陷入内核开销较大。实际系统大多采用组合方式比如Linux的NPTLNative POSIX Thread Library实现的就是“内核级线程模型”但用户空间还有用户级线程协程的库比如Go的Goroutine。理解这几种模型的区别能帮你更好地理解Go语言的调度器为什么那么强大——它在用户空间把大量Goroutine映射到少量内核线程上兼顾了切换速度和并行能力。8. 进程之间的悄悄话IPC机制盘点8.1 为什么进程不能直接通信既然各个进程的地址空间是相互隔离的它们之间如何传递数据这就引出了进程通信IPCInterProcess Communication。教材第二章一般会简单介绍后面章节会深入但这里有必要先建立一个全景。进程通信的方式可以分成几大类低级通信如信号、信号量和高级通信共享存储器、消息传递、管道等。低级通信传递的信息量小主要用于进程同步高级通信传递结构化数据用于真正“交换信息”。8.2 管道、消息队列、共享内存三种最常见的方案以下三种是面试中出现频率最高的IPC方式我用“生活化对比”帮大家记**管道Pipe**是最古老也最直观的方式相当于在两个进程之间拉了一根水管数据从一端流入另一端流出。管道是单向的如果你想双向通信需要建两根管道。Shell里的cmd1 | cmd2就是管道通信的经典应用grep error app.log | wc -l这句命令grep进程和wc进程之间就是用管道来传递数据。**消息队列Message Queue**相当于一个公共信箱一个进程往里放消息另一个进程取消息。消息有格式、有类型接收方可以按类型选择接收。相比管道消息队列的优势在于进程无需有血缘关系系统重启后消息还可以持久化。**共享内存Shared Memory**是最快的IPC方式因为它让多个进程直接映射到同一块物理内存读写不需要经过内核拷贝。本质上就是“你们共用一张办公桌谁都可以往上放文件、取文件”。但随之而来的问题是同步两个进程同时写同一块共享内存数据就乱了。所以共享内存通常要配合信号量Semaphore来用这正好呼应了第二章同步机制的学习。8.3 用Python一小段代码感受共享内存理论说再多不如跑一段代码。下面是Python的multiprocessing库实现共享内存的简单示例# shared_mem_demo.py import multiprocessing def writer(shared_value): for i in range(5): shared_value.value i print(fwriter set value {i}) def reader(shared_value): for _ in range(5): print(freader got value {shared_value.value}) if __name__ __main__: shared_value multiprocessing.Value(i, 0) p1 multiprocessing.Process(targetwriter, args(shared_value,)) p2 multiprocessing.Process(targetreader, args(shared_value,)) p1.start() p2.start() p1.join() p2.join()跑这段代码你会发现reader拿到的值不一定跟writer设置的值一一对应因为两个进程并发访问共享数据出现了竞争条件。要让输出规律起来需要加上Locklock multiprocessing.Lock() def writer(shared_value, lock): for i in range(5): with lock: shared_value.value i print(fwriter set value {i})这段小实验特别能说明问题共享资源本身很好用但并发访问必须配合同步机制。这个知识学透后你对第二章后面的PV操作、信号量机制都会有更扎实的理解。9. 学习这条路我踩过的坑和总结出的方法9.1 别急着背先用“角色扮演”理解进程调度很多人学操作系统陷入一个误区打开书就开始背概念背完就合书合书就忘。我第二次学这门课的时候换了个策略——把整个系统当成一个“人”来理解。比如理解调度你可以想象自己是操作系统的调度员手里有一堆进程每个进程有不同的状态和需求。CPU就是一个会议室的钥匙你有三个会议进程都在等这个钥匙用你该怎么分先来后到FCFS公平但可能让短任务的会议等太久优先给时间短的开会SJF总吞吐量高但长任务可能被饿死那就每个会议轮流用10分钟时间片轮转虽然切换成本高一些但大家都没意见。这样一想调度算法的取舍就非常自然不需要死记硬背。9.2 理论与实战的交叉验证是关键我在前文反复提到用Linux命令验证概念这里系统汇总一下建议实操的命令集# 观察进程树理解父子关系 pstree -p # 查看进程状态和PID ps -ef ps -l # 动态监控CPU和内存 top # 按P按M排序 # 查看某个进程的线程 ps -T -p PID # 查看进程打开了哪些文件 lsof -p PID每学一个概念就对应找一个实际场景去“看见”它。学PCB就去查ps -l里的PID和PPID学进程状态就用sleep加CtrlZ去制造挂起状态学僵尸进程就写一个父进程不回收子进程的小程序去故意制造出一个僵尸。这些操作并不难但做完之后你对概念的记忆深度是单纯的读书远远比不上的。9.3 面试和考试的高频问法提前准备根据我刷题和面试的经验第一章第二章常考的问题集中在这么几类概念对比类进程和程序的区别、进程和线程的区别、并发和并行的区别、阻塞和挂起的区别。这类问题不用死背画一张表或者能举出生活例子就够了。流程描述类进程从创建到终止经历了哪些状态转换fork()的返回值为什么有两个创建进程时操作系统做了什么这些问题一定要会“讲故事”把PCB的角色自然带进叙述里。判别分析类给你一个场景问并发是否可行共享是否有冲突这种题考查的是你能否把概念套到实际场景中我的经验是先画出前驱图再用Bernstein条件判断基本不会错。9.4 最后说点实在的操作系统这门课在国内很多高校被教成了“背诵课”但它的本质是一门“工程课”。第一章和第二章是整门课的骨架理解操作系统为什么存在你就有了全局视角理解进程是什么、怎么被描述、怎么被控制你就拿到了进入并发世界的大门钥匙。我在写这篇笔记时特意把自己第一次学时的困惑都翻了出来为什么会发明进程PCB到底在哪切换开销大在哪每个问题我都尝试用“工程师的视角”去回答而不是背定义。希望这篇笔记也能帮你建立同样的视角学完这两章之后当你再打开电脑的进程管理器看到一排排进程时能感受到它们背后那个忙而有序的“管家系统”。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询