
前两天有学弟来问我操作系统这门课到底怎么学为什么书翻完了、笔记抄了一遍合上照样心里没底。我第一反应就是想起自己当年抱着一本《计算机操作系统慕课版》第一章第二章啃到凌晨的日子。这两章是整个课程的地基第一章告诉你操作系统为什么存在、它站在什么位置第二章直接把你拉进进程这个系统中最核心的抽象概念。今天把自己这两章的学习笔记和复习心得整理出来教材里没展开的、老师上课一句带过的、做题容易翻车的统一补一遍。这篇文章适合正在上操作系统课的学生、准备考研复试的人以及工作几年回来补基础的同学参考。1. 第一章核心脉络操作系统到底是什么东西1.1 先记住这句话操作系统是接口、管家、虚拟机我用三个角色来理解操作系统的位置。第一个角色是接口操作系统站在用户程序和硬件之间程序员不需要直接操作磁盘、网卡这些硬件设备只要调用read、write、send这些系统调用接口就行底层怎么控制硬件是操作系统的事。第二个角色是管家计算机里的CPU、内存、I/O设备都是资源多个程序同时跑的时候谁先谁后、给谁多少内存都是管家在调度分配。第三个角色是虚拟机这是最抽象也最妙的视角——每个进程都以为自己独占了一整台机器有完整的内存空间和CPU时间实际上这是操作系统用虚拟化技术造出来的假象。这三个角色不是孤立的它们统一在操作系统的四个基本特征里并发、共享、虚拟、异步。很多人喜欢把并发理解成同时运行严格说不对单核CPU上并发是快速交替执行唯一真正同时运行的是多核上的并行。共享则跟并发绑定在一起多个进程同时访问同一个资源才有互斥访问和同步的问题。异步这个概念容易忽略说的是进程走走停停、速度不可预知但结果是确定的只要资源分配能保证公平。学习第一章的时候不要把目标定在把每个功能背下来而是把操作系统放在整个计算机系统的坐标里看清它往上有应用程序和用户往下是裸机硬件自己内部分层协作。这个坐标一旦建立后面讲进程、内存、文件系统的时候就不会迷路。1.2 发展历程批处理、分时、实时三兄弟怎么来的操作系统不是一天变成现在这样的它的发展逻辑非常清晰人觉得操作效率太低所以要搞批处理批处理调试太痛苦所以要搞分时交互有些场景对响应时间有硬性要求于是又出现了实时系统。把这个因果链记住比死背年代事件强得多。单道批处理时代作业一个接一个、CPU和人之间频繁切换内存里同时只装一道程序CPU经常因为等I/O而空闲。后来出现了多道批处理内存里驻留多道程序一道程序I/O时CPU立刻切换去执行另一道资源利用率上来了但用户完全没法交互程序出了问题只能等全部跑完看输出。分时系统把CPU时间切成很小的时间片轮流分给每个用户终端大家各自敲命令、各自调试感觉像是独占主机这靠的是时间片轮转。实时系统的关键词是截止时间它强调在规定时间内完成任务又分硬实时和软实时比如工业控制、飞机系统就是硬实时多媒体播放的实时性要求相对宽松。很多教材会提一个经典演进图人工操作阶段到监督程序、批处理再到多道批处理、分时、实时最后到现在的通用操作系统。这个演进过程我在复习时自己手画过一遍时间线比直接背文字记得牢。1.3 四大特性和五大功能考试的高产地第一章的大题和填空题十有八九落在四大特性和五大功能上。四大特性前面讲过这里重点说五大功能它是按照资源类别划分的处理机管理、存储器管理、设备管理、文件管理和用户接口。处理机管理本质上是进程管理因为CPU只能执行进程所以处理机管理包括进程控制、进程同步、进程通信、进程调度。存储器管理负责内存的分配回收还要保证各进程的内存区域互不干扰并且把逻辑地址转换成物理地址。设备管理处理I/O设备的分配和驱动核心目标是让用户用统一接口访问不同设备同时提高CPU和设备之间的并行程度。文件管理解决的是信息怎么存的问题负责文件的目录组织、存储空间分配、存取控制和数据保护。用户接口好理解就是命令接口、程序接口和图形接口前两个分别对应命令行和系统调用图形接口比如Windows桌面。复习这一块我有一个笨办法每讲一个功能在纸上写一个具体的例子对应上。比如处理机管理就写进程切换时保存和恢复上下文文件管理就写我在Linux里创建的a.txt存在哪个目录、哪个磁盘块。概念一旦跟实例绑定考试时哪怕题目换个说法也能认出来。1.4 中断、系统调用与系统态理解内核的钥匙这一节如果只看慕课视频容易一带而过但它其实是连接第一章和第二章的关键。现代CPU至少支持两种执行状态用户态和核心态也叫管态、内核态。用户程序跑在用户态权限受限不能直接执行特权指令一旦需要操作系统帮忙做事通过系统调用陷入核心态由操作系统代劳。这个转化过程靠的正是中断机制。中断分为外中断也叫中断和内中断也叫异常、陷入。外中断来自CPU外部比如时钟中断、I/O完成中断内中断来自CPU内部比如缺页异常、除零错以及主动执行陷入指令。系统调用属于内中断里主动触发的一种比如Linux里用户态的read()通过软中断或专门的指令陷入内核再返回用户态。理解这个过程后面学进程状态转换里的阻塞就会更顺因为等待I/O的进程往往是发起了系统调用后在内核里被挂起。我建议学到这里手动在Linux里做个小验证用strace ls命令观察一个再简单不过的ls也调用了execve、openat、getdents64等一堆系统调用。看完你就明白用户态和核心态之间一天要来回穿梭多少次操作系统这个管家有多忙。教材反复强调的操作系统是用户与计算机硬件之间的接口本质上就是指这一层系统调用接口。1.5 第一章学习容易踩的坑第一个坑是把并发等同于并行。考试爱出判断题并发是逻辑上同时发生并行是物理上同时执行单核CPU上不可能有并行但可以有并发多核下并发和并行并存。第二个坑是把多道程序设计和分时混为一谈多道强调的是内存中同时存放多道程序、提高资源利用率分时强调的是时间片轮转、实现交互。第三个坑是忘记操作系统本身也是程序它运行在核心态也需要占用内存和CPU常见考题是操作系统是系统软件还是应用软件以及操作系统的代码运行在哪里。还有一个小地方很多教材提到操作系统的虚拟机特性时举的例子是一台物理机上跑多个虚拟机软件其实这跟操作系统的虚拟化不完全是一回事。操作系统提供的虚拟是每个进程一个逻辑地址空间、独享CPU这种抽象而不是虚拟化软件那种软件模拟整套硬件。概念别串。2. 第二章上半场进程的描述与状态2.1 为什么要引入进程程序并发执行惹的祸第一章讲多道程序的好处第二章马上开始算账程序并发执行会带来什么麻烦。顺序执行时程序有顺序性、封闭性、可再现性你算的结果跟执行速度无关。可是并发执行时程序之间共享资源、相互制约执行就变成了间断的一个程序还没跑完可能被另一个程序打断执行速度也不再封闭结果可能受到其他程序的影响失去封闭性同样的输入由于调度顺序不同输出还可能不一样失去可再现性。为了解决这个怎么描述并发程序的动态执行过程的问题就引入了进程这个概念。教材上的定义是进程是程序在一个数据集合上的一次执行过程是系统进行资源分配和调度的独立单位。注意关键词一次执行过程它强调动态性程序是静态的、永久的进程是动态的、生命周期有限的。这个区分是第二章最基础也最爱考的题目。我在复习时常用一个比喻程序是菜谱进程是按照菜谱实际炒菜的过程。菜谱可以一直存在但炒菜过程有开始、有暂停、有放佐料、有出锅还会跟同时炒的另外几道菜争抢炉灶和锅具。这个比喻帮我记住了程序的静态性和进程的动态性也顺便理解了为什么进程需要状态。2.2 进程长什么样PCB加程序段加数据段一个进程实体在内存里包含三部分程序段、数据段、进程控制块。程序段是进程要执行的代码数据段是程序运行时使用的数据进程控制块是操作系统为了管理进程设置的专门数据结构存着描述进程状态和控制进程运行的全部信息。PCB是其中最重要的部分教材上有个经常出题的表述PCB是进程存在的唯一标志。也就是说进程创建时先创建PCB进程结束时先回收PCB没有PCB就不算一个进程。PCB里到底装了什么一般可以归纳成四类。第一类是进程标识符包括外部标识符比如进程名字、PID和内部标识符唯一识别第二类是处理机状态信息也就是通用寄存器、指令计数器、程序状态字、栈指针这些现场数据进程切换时先把它们存进PCB再调度回来才能恢复现场第三类是进程调度信息包括进程状态、优先级、等待事件等第四类是进程控制信息比如程序和数据在内存中的地址、进程占用的资源清单、进程同步通信信息。复习PCB时我想推荐一个反推法假设你是操作系统要让一个进程能在被打断后从断点继续跑你需要预先记住哪些东西寄存器现场要不要保存下一步执行到哪条指令要不要记占了多少内存要不要记这样反推一遍PCB的每项字段都有了意义而不是干背结构体。后面学线程的时候还会出现TCB两者对比记忆效果更好。2.3 三态模型与带掛起的状态进程状态转换图是第二章必考内容先记住最基本的三种状态就绪态、执行态、阻塞态。就绪态指进程已经获得CPU以外的所有资源只等分配CPU执行态指进程正在CPU上运行阻塞态指进程因等待某个事件而暂停哪怕给你CPU也跑不了。三态之间的转换关系是就绪被调度进入执行执行被时钟中断抢占回到就绪执行因等待事件进入阻塞等待事件完成回到就绪。注意阻塞不可能直接变成执行执行也不可能直接进入就绪执行是可以被抢占回到就绪的但阻塞不能直接变成就绪阻塞等待的事件发生后就进入就绪等待调度这是标准。转换图里的两个方向最容易记错一是执行到就绪是时间片用完或被高优先级抢占不是自发给出的二是阻塞到就绪是事件发生比如I/O完成而不是直接获得CPU。前者是我还没干完但被迫让位后者是我终于等到了但不代表马上轮到我。带掛起的状态模型通常有四态或五态比三态多了一个活动/静止的维度。引入掛起的原因很多比如系统资源紧张、用户调试、父进程请求、定时检查。掛起可以是进程自己主动挂起自己也可以是操作系统挂起某个进程被掛起的进程从内存调到外存即使状态就绪也不能被调度。学习时把掛起理解成冻结就行它是比阻塞更深层的暂停阻塞是等着事件掛起是想直接挪出内存。2.4 进程控制原语操作的四个动作进程控制包括进程创建、终止、阻塞、唤醒以及进程切换。教材强调这些操作要用原语实现原语的特点是执行过程中不可被中断要么全做要么不做。为什么因为创建进程要申请PCB、分配资源、初始化这些步骤必须一气呵成否则半路被插个进程资源分配就可能乱套。创建进程的核心步骤是申请空白PCB、为进程分配运行所需资源、初始化PCB、把进程插入就绪队列。终止进程则要逆向操作根据标识符找到PCB、读状态、若正在运行则立即剥夺CPU、终止其所有子孙进程、回收它占用的资源、删除PCB。阻塞原语的动作是停止当前进程执行、修改状态为阻塞、插入等待队列、转调度程序。唤醒原语则相反把进程从等待队列移出、修改状态为就绪、插入就绪队列。阻塞和唤醒必须成对使用而且唤醒原语可以由其他进程甚至中断处理程序调用阻塞只能是进程自己调用自己。进程切换是本节的实操重点它并不等于简单的状态改一改而是要从当前进程上下文切到下一个进程上下文先保存当前进程的CPU现场到PCB再更新当前进程PCB和队列选择新进程并恢复其PCB中的现场最后更新内存管理数据结构。面试题很喜欢问进程切换和模式切换用户态到核心态的区别模式切换不一定要切换进程同一个进程进内核再回来也可以进程切换必然涉及模式切换因为调度器跑在内核里。2.5 线程进程内的轻量级执行流第二章后面通常会讲线程。引入线程是为了减小程序并发执行时的时空开销。进程切换开销大因为要切换地址空间和资源而同一进程内的多个线程共享地址空间切换线程不用换内存映射轻便太多。教材定义线程是进程内一个相对独立的执行流是CPU调度和分派的基本单位进程则是资源分配的基本单位。线程与进程的区别要记清楚进程拥有资源线程基本不拥有系统资源只拥有少量运行现场同一进程内的线程共享进程的地址空间和资源而进程之间资源相互独立线程的调度开销远小于进程线程之间同步通信比进程间通信简单因为直接共享内存。系统级上的体现是getpid返回的PID所有线程一样而gettid每个线程不同很多阅读过Linux内核源码的人都会有这个直觉。线程模型分用户级线程和内核级线程多对一、一对一、多对多是常考点。用户级线程在用户空间管理内核感知不到调度单位仍然是进程好处是切换快、不依赖内核但一个线程阻塞会让整个进程阻塞内核级线程由内核管理调度每个线程独立调度阻塞并发能力高但切换开销更大。现在常见的Linux用一对一模型也就是NPTL线程库的实现。3. 第二章下半场同步、互斥与通信3.1 同步与互斥先分清关系进程同步的内容几乎必考但很多人一开始把同步和互斥搞反。同步是指多个进程为了完成同一任务而相互协作执行顺序上有某种先后制约比如A产生数据、B消费数据B必须在A之后执行这叫直接制约关系。互斥是指多个进程同时竞争同一个临界资源只能轮流使用这叫间接制约关系。一句话总结同步是合作的拍子互斥是资源的独占。教材会引入临界资源和临界区的概念。临界资源是每次只允许一个进程访问的资源如打印机、共享变量进程中访问临界资源的那段代码叫临界区。四个原则空闲让进、忙则等待、有限等待、让权等待。前两个保证正确性后两个提升公平性和CPU利用率其中让权等待指的是进不了临界区的进程应释放CPU这个很多同学会忽略但在评价同步方案时会用到。学习这一节我建议自己画一张同步VS互斥的对比表左边写定义、右边写例子、下面写对应的制约关系。不要只背概念考试爱给场景题比如多个进程同时读一个文件司机和售票员合作你要能说出属于同步还是互斥、访问的资源是什么。3.2 信号量P操作和V操作到底在干什么信号量机制是最经典的同步工具考试让你写wait、signal也叫P操作和V操作。信号量是一个整数加一个等待队列P操作执行S减一如果结果小于0就把进程阻塞V操作执行S加一如果结果不大于0就唤醒一个等待进程。这个小于0和不大于0的判定是高频考点别偷换条件。怎么理解信号量的值如果信号量初始为1表示一个资源P之后变为0另一个进程再来P变负就得排队这实现的是互斥。如果初始为N表示同类资源有N个实现的是资源计数控制。用于同步时经常把信号量初值设为0A进程V一下、B进程P一下完成先执行后执行的先后关系。写生产者消费者例子时有几个容易错的点。第一缓冲区互斥信号量mutex和资源信号量empty、full三者的P操作顺序不能随意换如果先P(empty)再P(mutex)是常规写法反过来先锁缓冲区再发现没有空间就可能导致死锁。第二V操作没有等值检查唤醒要放在释放锁之前还是之后实践中建议先V资源信号量、再V互斥锁避免产生不必要的调度。理解信号量时把它想象成一个发号牌系统P是想领号牌没号牌就排队V是归还号牌顺便叫下一个排队的人。3.3 生产者消费者、读者写者、哲学家进餐经典同步问题不同教材讲的顺序细节各有不同但核心不变。生产者消费者解决的是有界缓冲区下生产者不能往满缓冲区写、消费者不能从空缓冲区读用empty、full、mutex三个信号量搞定。读者写者问题里读者可以同时读写者必须独占还要防止写者饥饿。哲学家进餐问题关键在于让每个哲学家先拿左边筷子、再拿右边筷子会导致环路等待死锁解决办法是限制最多四人同时拿筷子、或让奇数号先拿左再拿右、偶数号相反或一次拿两根筷子的原子操作。我当年复习时总结过一句口诀先资源信号量再互斥信号量V的顺序无所谓但P顺序别乱。为什么强调V的顺序无所谓因为V操作不会导致进程被阻塞只是释放资源谁先谁后只影响唤醒顺序不影响正确性。P的顺序会出问题因为P可能让进程睡眠如果睡眠时还占着别的锁别的进程进不来就可能死锁。读代码题的时候建议先把进程的行为拆成生产临界区/消费临界区再往里插P和V。比如生产者第一步P(empty)判断有没有空位第二步P(mutex)进临界区第三步写入缓冲区第四步V(mutex)出临界区第五步V(full)通知消费者。只要这个框架在题目怎么变形都不怕。3.4 进程通信不是共享内存那么简单进程通信这里教材一般分三类共享存储、消息传递、管道通信。共享存储是最高效的多个进程映射到同一块内存区域直接读写但要自己解决同步互斥比如上面说的共享缓冲区就属于这种。共享内存通信需要两个进程的地址空间有交集或通过映射也是Linux下最常用的IPC方式之一。消息传递分为直接通信和间接通信。直接通信是发送方指明接收进程ID接收方指明发送进程ID消息直接挂在接收进程的消息队列上间接通信是双方通过一个中间实体信箱通信发送消息放进信箱接收方从信箱取消息。信箱机制的好处是通信双方解耦松散耦合场景更好用。管道通信是基于文件系统的通信方式管道就是一个共享文件写进程向管道写、读进程从管道读。它的特殊性在于先进先出、单向流动、大小有限。Linux的命令行里用的竖线|就是匿名管道shell会把左右两个命令用pipe连起来ls的输出恰好是grep的输入。学习通信这一节时可以把同步和通信对照看同步解决的只是时序问题不一定传递数据通信要传递真正的数据。如果一个进程要告诉另一个进程我算完了用信号量就行但要说清楚我算出来的结果是多少就得用共享内存或消息传递。搞清楚这个区别遇到为什么有了同步还要通信的问答题就不会懵。4. 章节之间的线程问题4.1 线程为什么比进程轻这一节单独拿出来说是因为很多考点故意把进程和线程放在一起对比。进程拥有独立地址空间、文件描述符表、信号处理等一整套资源线程则共享这些资源。线程切换只切换栈和寄存器上下文进程切换要切换页表、刷新TLB开销相差很大。因此多线程模型更适合频繁创建销毁、任务间需要大量数据交换的程序比如Web服务器为每个请求创建一个线程。教材里还有一句线程是独立的调度单位但不是独立的资源拥有单位。这句话是判断线程和进程的王牌依据。考试如果问以下哪些是进程独有、哪些是线程共享你就照这句话推代码段、数据段、堆、全局变量是进程内线程共享的栈和寄存器现场是每个线程独立的因为每个线程都要有自己的执行轨迹。注意文件描述符表和当前目录信息也属于进程级共享子线程打开的文件其他线程能直接用。4.2 用户级线程与内核级线程的区别用户级线程ULT完全由用户空间的线程库管理内核不知道线程的存在调度以进程为单位。好处是线程切换不陷入内核非常快坏处是一个线程发起阻塞系统调用整个进程都会阻塞多核上不能把多个线程分配到不同核心并行执行。内核级线程KLT由内核管理每个线程都是调度单位能利用多核一个线程阻塞不影响其他线程但切换代价高创建和销毁也要进内核。三种模型按教材说法是多对一、一对一、多对多。多对一是多个用户线程映射到一个内核线程优点是管理开销低缺点是无法并行。一对一是每个用户线程对应一个内核线程并发能力强但线程数量受内核限制。多对多模型是折中方案用户线程数与内核线程数灵活对应兼顾并发和开销。Linux用的是一对一配合轻量进程LWP机制实现。我给这部分复习时做的类比进程像一家公司内核级线程像公司里的正式员工用户级线程像公司雇佣的临时工。正式员工每个都有独立的工位和权限被公司统一管理临时工挂靠在正式员工名下由项目组自己调配开销低但正式员工请假临时工也跟着歇。这个类比能帮你记住多对一模型的主要毛病。5. Linux实操把这两章的概念跑起来5.1 用ps/pstree看进程树和状态学操作系统不碰Linux等于出门没带地图。我强烈建议学完这两章以后打开一个Linux终端把这些命令过一遍。ps -ef或者ps aux可以列出所有进程看到PID、PPID、STAT这些字段。STAT栏里R表示运行、S表示睡眠、D表示不可中断休眠、Z表示僵尸这些状态几乎就是教科书三态模型的现实映射。pstree -p能画出整棵进程树你会发现所有用户进程的祖先几乎都是systemd或者initPID为1。这印证了教材里讲的进程创建通常由父进程发起形成树形结构。想找某个特定进程的信息用pgrep -a进程名比如pgrep -a sshd或者用ps -ef | grep sshd都行。想动态监控全局状态用top或htop能实时看到CPU占用、内存占用、每个进程的状态和优先级D状态的进程还经常跟I/O等待挂钩。5.2 去看PCB/proc目录就是活的教科书Linux把每个运行进程的信息都暴露在/proc目录下这不比教材里的PCB结构图来得更直观选一个进程比如echo $$然后cd /proc/$(echo $$)用cat status查看内容里面清清楚楚写着Name、State、Pid、PPid、VmRSS、Threads等字段。对照教材讲PCB的四大类内容标识符、处理机状态、调度信息、控制信息你逐行看绝对能对上号。再结合实操看上下文信息用cat /proc/其PID/stat可以看到进程状态和各项计数但格式比较难读建议用ps -o flag -p PID来看更清楚。真想深入就去看内核源码里task_struct结构体你会发现教材里的PCB在真正的Linux内核里叫task_struct字段比教材多得多但核心思想一脉相承。我当年学完这一章后去翻了task_struct的include/linux/sched.h有一种教材上的图活了的感觉。5.3 fork一次输出两次亲手理解进程创建进程创建在教材里是一段原语描述在Linux里就是fork()一个函数。随便写一段几行代码让主进程输出一条Hello然后再fork一次你会发现总共输出了两条。原因很简单fork成功返回后父进程和子进程各自从fork调用处继续执行所以printf代码被执行了两次虽然源码里只写了一遍。这直接体现了进程是程序的动态执行过程这一概念也能直观理解PCB复制时子进程有了自己的运行现场。用getpid()和getppid()分别打印自己的PID和父进程PID能看到父子关系再配合pstree就能把进程树对上。如果想看更复杂的执行流试试fork多个子进程让它们用sleep分别睡不同秒数然后观察ps的STAT状态变化。这一系列小实验做下来第二章的进程创建、状态转换、父子关系就不再是纸面上的图形了。5.4 僵尸进程教科书里常考实操里常见僵尸进程这个概念很多同学在教材里见过但不理解直到自己写了个fork程序才发现进程列表里冒出一堆Z状态的尸体。原因是子进程先于父进程退出但父进程没有调用wait()或waitpid()来回收子进程的退出状态子进程的PCB就没法从系统中彻底清除于是处于Zombie状态。解决办法有几种父进程主动调用wait/waitpid或使用signal(SIGCHLD, SIG_IGN)让内核自动回收或者在子进程退出前用kill()杀掉的其实是父进程的wait信号。排查时用ps aux | grep Z找出僵尸再ps -ef查它的PPID是谁如果父进程也是僵尸或已经退出那僵尸会被init进程接管并最终清理。自己在写实验代码时养成父进程wait的习惯就不会被这个坑恶心到。6. 高频考点和复习避坑建议6.1 这两章常见的题目类型第一章的填空选择多集中在操作系统的目标与作用、四大特性、五大功能、中断分类、用户态与核心态的区别。大题常见的是给一段场景让你说操作系统在中间做了什么比如printf一个字符串经过哪些环节本质上考察系统调用和中断机制。第二章题目类型更丰富第一类概念题进程和程序的区别、进程与线程的区别、PCB的内容第二类计算题给定调度场景算状态转换、等待时间第三类信号量题写生产者消费者或者给代码分析同步是否合理第四类简答题问进程创建步骤、进程切换步骤。考试前我建议把教材上的课后题全部做一遍特别是第2章的信号量部分建议一个例子都不要放过因为考试很难跳出生产者消费者、读者写者、哲学家进餐这三个模子。做完之后把每道题的信号量初值、P/V顺序、为什么这样设计写一遍理由比单纯把答案抄下来更有用。6.2 几个我当年记混乱后来才搞明白的点第一就绪队列里放的是PCB不是进程本身。所有调度和队列操作都是对PCB操作这跟前面说的PCB是进程存在的唯一标志呼应。第二阻塞态进程被唤醒后不是直接进入运行态而是进入就绪态它还要跟其他就绪进程一起竞争CPU所以阻塞唤醒和调度是两码事。第三进程挂起和进程阻塞不同挂起可以是被动的比如内存不够被换出阻塞则是进程自身等待某种事件。第四P操作可能阻塞V操作不会阻塞所以V操作的顺序对正确性几乎无影响而P操作的顺序会产生竞争条件甚至死锁。很多同学复习到后面容易把进程切换和进程调度搞混。进程调度是选择下一个运行进程的策略过程比如先来先服务、短作业优先、时间片轮转进程切换是实际保存上下文、恢复上下文的机制过程。调度算法可以没有切换但切换总发生在某次调度决策之后。这个区分在第三章会特别重要现在先埋下伏笔。6.3 一份给新手的复习顺序清单如果你刚开始学这两章别上来就啃代码题。我建议按下列顺序走一遍先通读教材第一、二章的正文把老师布置的慕课视频看完注意暂停做随堂练习然后自己画一张两章的知识树一级标题列引论、进程描述、进程控制、进程同步、进程通信、线程二级再往下挂具体知识点接着做课后选择题用来查漏补缺然后做信号量大题至少独立写出生产者消费者的完整代码再抬头看实操打开Linux终端把ps、/proc、fork小实验过一遍最后关上书本把每一个状态转换图手画一遍把PCB结构默写一遍。这套顺序核心是先懂Why再记What先搞清楚为什么要有进程、为什么要信号量再记各种定义和字段不然很容易陷入背了忘、忘了背的循环。如果时间实在紧优先保证理解三态转换、PCB组成、信号量P/V三分、进程线程区别这四个点这四个点是整个操作系统课后续内容调度、死锁、内存管理的基石。我个人实际操作中很深的体会是操作系统不能只靠看必须配合画和跑。画状态图、画PCB结构图、画P/V执行流程图比盯着一页页PPT有用得多跑一遍Linux命令看一次进程的出生和消亡比闭眼背十遍进程是程序的一次执行过程更能内化成自己的理解。第一、第二章啃下来后面的存储管理和文件系统虽然也不轻松但至少不会再产生这到底在说啥的迷茫感。