第二章(1) 操作系统——进程与线程(英文标注)

📅 2026/6/27 3:10:17
第二章(1) 操作系统——进程与线程(英文标注)
一 .引入和基本概念2.1 程序程序是存储在磁盘上的静态指令集合。它是一个文件.exe、可执行文件是被动的。2.2 进程与线程的引入2.2.1 进程的引入在早期的单道程序时代程序顺序执行串行具有可再现性简单来说同一套输入多次运行结果一样。但CPU利用率极低I/O操作时CPU空闲。后来引入了多道程序设计让多个程序同时驻留内存并发执行。这时问题出现了程序并发执行时由于CPU不断切换程序失去了封闭性执行结果与执行速度有关出现了“不可再现性”。这个问题的本质是“程序”这个概念无法描述“正在执行中”的动态变化。因此引入了进程Process。2.2.2 线程的引入虽然进程实现了并发但随着时间的推移发现了以下问题切换开销巨大进程是资源拥有者拥有独立的地址空间。当CPU从一个进程切换到另一个进程时必须切换整个地址空间、更新页表、刷新TLB快表耗时极长。通信成本高昂进程间内存相互隔离想要通信必须借助内核IPC如管道、消息队列速度慢且复杂。无法满足“内部并发”比如打开一个浏览器一边下载一边渲染页面如果只用进程来做创建多个进程极其浪费资源。本质是进程切换时切换地址空间的成本远远跟不上CPU可能的执行速度。而如果将资源分配与调度执行分离。线程切换无需切换地址空间开销极小从而使得并发执行的粒度能够匹配上CPU的高速处理能力。因此引入了线程Thread。2.3 进程和线程的概念对比维度程序 (Program)进程 (Process)线程 (Thread)简要介绍静态的指令集硬盘上的文件动态的执行实例运行中的程序进程内的执行路径轻量级运行流核心角色提供执行内容和蓝图资源分配的基本单位CPU调度的基本单位存在形态静态的、被动的动态的、主动的有生命周期动态的、主动的依附于进程生命周期永久的文件不删就一直存在临时的创建而生终止而亡临时的随进程创建/消亡或动态创建/销毁资源拥有不拥有任何资源仅占磁盘空间拥有独立资源独立地址空间、文件、端口共享进程资源仅拥有私有栈和寄存器内存布局仅有代码段 静态数据完整的虚拟地址空间代码数据堆栈同进程内线程共享地址空间仅栈独立通信方式不涉及通信无法运行进程间通信IPC管道、消息队列、共享内存、Socket需陷入内核开销大直接读写共享内存零拷贝无需内核介入极快上下文切换不涉及重量级切换需切换页表、刷新TLB/缓存耗时约1~10微秒轻量级切换仅切换寄存器和栈指针无需切换地址空间耗时不到1微秒系统开销几乎为零仅为存储创建/撤销开销大需分配独立资源创建/撤销开销小仅需分配TCB独立性相互独立静态文件高拥有独立地址空间一个进程崩溃通常不影响其他进程低共享地址空间一个线程崩溃可能导致整个进程崩溃操作系统感知感知不到当作普通文件管理强烈感知通过PCB管理看情况内核级线程感知用户级线程不感知进程存在的唯一标识——PCBProcess Control Block进程控制块字段作用补充pointer指针指向下一个PCB的地址用于将多个PCB链接成队列如就绪队列、阻塞队列。这就是操作系统把进程挂入“就绪队列”或“阻塞队列”的具体实现方式。process number进程号/PID进程的唯一身份证号整数。父进程fork()返回的那个数字。process state进程状态记录当前进程处于就绪、运行、阻塞、挂起等哪种状态。OS根据它决定下一步动作。program counter程序计数器/PC记录进程下一条要执行的指令在内存中的地址。上下文切换Context Switch的核心。当进程被踢下CPURunning→Ready时OS把PC值存到这里当进程再次上CPU时OS从这里取出PC恢复执行。registers寄存器集合保存CPU内部所有通用寄存器、栈指针、状态字的值。进程切走时寄存器的值必须原封不动存到这里否则回来时数据全乱了memory limits内存界限记录进程占用的内存基址和长度防止它越界访问其他进程的内存。保证进程间地址空间隔离这是进程作为“资源拥有者”的关键凭证。list of open files打开文件列表记录进程当前打开的所有文件、管道、网络连接的指针。这就是进程“拥有资源”的具体体现。线程共享这个列表所以线程间打开的文件是共用的。上下文切换Context SwitchCPU从正在运行的process、thread切换时保存当前运行现场、加载新任务现场的全过程2.4 进程的状态2.4.1 含义状态含义New新建态操作系统刚刚收到创建请求正在分配PCB进程控制块和初始资源但还没允许它进入系统。Ready就绪态进程具备了一切运行条件内存、资源都齐了在就绪队列里排队等待调度。Running运行态进程此刻正占用CPU执行指令。Waiting/Blocked阻塞态进程在运行中因资源需要或等待其他进程响应主动放弃CPU等待。Terminated终止态进程结束操作系统回收它占用的所有资源PCB即将被销毁。2.4.2 进程控制process operation—— 状态切换原语Primitive原语是由若干条机器指令构成、执行过程不可中断的一段内核程序用于完成特定进程控制功能。内核底层、原子执行是实现同步互斥 / 进程管理的基础转换线触发事件执行的操作原语执行New → Ready系统允许进程从外存进入主存创建原语 (Create)分配PCB、分配初始资源、初始化PCB操作系统内核父进程调用fork()由内核响应Ready →Running调度程序选中该进程调度原语 (Dispatch/Schedule)从就绪队列摘出恢复进程上下文到CPU操作系统调度器内核的调度模块Running → Ready时间片用完 / 被高优先级抢占中断处理原语 (Interrupt Handle)保存当前进程上下文到PCB将其挂入就绪队列操作系统内核时钟中断或I/O中断处理程序强制触发Running →Waiting请求I/O / 等待资源 /wait()阻塞原语 (Block/Wait)保存现场将进程从运行态移出挂入阻塞队列进程主动调用例如调用read()、wait()系统调用Waiting → ReadyI/O完成 / 资源到位 / 事件发生唤醒原语 (Wakeup/Signal)将PCB从阻塞队列摘下状态改为就绪挂入就绪队列操作系统内核设备中断处理程序或signal释放资源时触发Running→Terminated正常结束 / 异常 / 被杀死终止原语 (Exit/Kill)回收PCB、回收所有内存和资源、通知父进程进程主动调用exit()或父进程/内核强制kill创建原语 (Create) -- 父进程与子进程资源共享Resource sharing全部、部分[fork()写时复制COW]、不共享[forkexec]执行Execution同时执行父进程会阻塞直到子进程终止进程的创建、程序替换、同步与终止的UNIX/Linux 系统编程代码#include stdio.h void main(int argc, char *argv[]) { int pid; /*fork another process */ // 创建子进程系统调用fork() pid fork(); // 分支1fork调用失败内存不足/进程数上限 if (pid 0) { fprintf(stderr, Fork Failed); // 标准错误流打印失败信息 exit(-1); } // 分支2pid 0 代表当前是子进程 else if (pid 0) { execlp(/bin/ls, ls, NULL); // 加载执行ls命令替换子进程全部内存镜像 // execlp执行成功后后续代码永远不会运行执行失败才会向下执行 } // 分支3pid 0 代表当前是父进程pid是子进程PID else { wait(NULL); printf(Child Complete); exit(0); } }2.5 进程的通信IPCInter-Process Communication2.5.1 两个的独立进程怎么找到对方共同的“内核对象”管道、共享内存、消息队列类型代表机制如何找到对象适用范围匿名 (Anonymous)匿名管道pipe()靠继承。父进程通过fork()把管道的文件描述符直接传给子进程。仅限于有亲缘关系父子/兄弟进程。命名(Named)命名管道FIFO、共享内存、消息队列、Socket靠路径名或Key。进程根据事先约定好的字符串如/tmp/my.pipe或12345向内核“申请”打开。任意进程无亲缘关系也能通信。2.5.2 通信方式IPC方式通信范围同步/异步数据边界速度排名典型应用信号 (Signal)单机异步无数据负载仅传信号编号极快进程异常终止、定时器、SIGCHLD管道 (Pipe)匿名(亲缘) / 命名(任意)同步阻塞无格式字节流无边界慢Shell命令连接ls | grep消息队列 (MQ)任意进程单机通常异步有边界数据报按类型/长度取中等异步任务分发、日志收集共享内存 (SHM)任意进程单机同步需配合锁原始内存块无格式极快数据库缓存区、高速数据交换信号量 (Semaphore)任意进程单机同步工具计数器整数非数据通道快保护共享资源互斥锁/读写锁套接字 (Socket)跨网络也可单机同步/异步TCP 字节流无边界UDP 数据报自带边界较慢Web服务器、浏览器、分布式系统