顺序程序与顺序环境 (Sequential Program & Environment)
多道程序设计 (Multiprogramming)
并发环境与并发程序 (Concurrent Environment & Program)
执行 -> 停 -> 执行
)。进程 (Process)
进程状态 (Process States)
进程状态转换模型 (State Transition Models)
三状态模型:
graph LR
Ready(就绪) --> |调度|Running(运行)
Running --> |时间片到/高优先级进程抢占|Ready
Running --> |等待事件|Waiting(阻塞)
Waiting --> |事件发生|Ready
mermaid五状态模型:
graph LR
New(创建) --> |提交|Ready(就绪)
Ready --> |调度|Running(运行)
Running --> |时间片到/高优先级进程抢占|Ready
Running --> |等待事件|Waiting(阻塞)
Waiting --> |事件发生|Ready
Running --> |完成|Terminated(终止)
mermaid七状态模型:
graph LR
New(创建) --> |提交|Ready(就绪)
Ready --> |调度|Running(运行)
Running --> |时间片到/高优先级进程抢占|Ready
Running --> |等待事件|Waiting(阻塞)
Waiting --> |事件发生|Ready
Running --> |完成|Terminated(终止)
Ready --> |挂起Suspend|SReady(就绪挂起)
SReady --> |激活Activate|Ready
Waiting --> |挂起Suspend|SWaiting(阻塞挂起)
SWaiting --> |事件发生|SReady
SWaiting --> |激活Activate|Waiting
New --> |提交|SReady
Running --> |挂起Suspend|SReady
mermaidLinux 进程状态: 包括 R (TASK_RUNNING)
(运行或就绪), S (TASK_INTERRUPTIBLE)
(可中断睡眠), D (TASK_UNINTERRUPTIBLE)
(不可中断睡眠), T (TASK_STOPPED)
(停止), Z (TASK_DEAD - ZOMBIE)
(僵尸) 等。其状态模型与理论模型有所差异,更贴近实现。
XV6 进程状态: UNUSED
, USED
, SLEEPING
, RUNNABLE
, RUNNING
, ZOMBIE
。这是一个简化的教学模型。
不同模型的意义: 体现了 机制和策略分离,基础状态转换是机制,增加挂起等状态是为了实现更复杂的内存管理和负载均衡策略。
进程控制块 (Process Control Block, PCB)
task_struct
, Windows 的 EPROCESS
/KPROCESS
/PEB
, Solaris 的 proc_t
。真实系统中的PCB结构非常庞大复杂。进程地址空间 (Process Address Space)
malloc
, new
),向上增长。fork()
创建子进程时,并不立即复制整个地址空间,而是让父子进程共享物理页面,并将页面标记为只读。当任何一方尝试写入时,触发异常,内核才真正复制该页面,使其私有化。这极大地优化了 fork()
的效率,特别是 fork()
后立即 exec()
的情况,因为exec()
会替换整个地址空间,使得大部分共享页面在被写入前就已被丢弃,从而避免了不必要的复制开销。cat /proc/<PID>/maps
(Linux) 可以查看进程的虚拟内存区域布局。进程队列 (Process Queues)
原语(Primitive)是完成某种特定功能的一段程序,具有不可分割性或不可中断性,即原语的执行必须是连续的,在执行过程中不允许被中断,也称为原子操作(Atomic)。
进程控制操作完成进程各状态之间的转换,由具有特定功能的原语完成:
进程创建的时机:
进程终止的时机:
进程终止的各种事件:
进程创建的主要步骤:
不同操作系统的实现:
进程撤销的主要步骤:
不同操作系统的实现:
处于运行状态的进程,在其运行过程中期待某一事件发生(如等待键盘输入、等待磁盘数据传输完成、等待其它进程发送消息),当被等待的事件未发生时,由进程自己执行阻塞原语,使自己由运行态变为阻塞态。
不同操作系统的实现:
UNIX系统提供了一系列系统调用来实现进程控制:
这些系统调用之间的关联(shell、fork()、exec()、wait())体现了UNIX进程管理的设计哲学,通过简单而正交的原语组合实现复杂功能。
UNIX的fork()实现步骤:
优化方案: Linux的解决方案是利用存储管理模块中的”写时复制技术”COW(Copy-On-Write)对fork()进行了优化。
重新审视fork函数:
线程 (Thread)
线程的属性:
多线程进程模型: 一个进程包含一个PCB和多个线程控制块 (Thread Control Block, TCB)。所有TCB共享进程的地址空间和资源,但每个TCB有自己独立的PC、寄存器和栈。
用户级线程 (User-Level Threads, ULT)
核心级线程 (Kernel-Level Threads, KLT)
混合模型 (Hybrid Implementation)
为什么引入协程?
协程是什么?
协程怎么用?
async def
)。await
, yield
) 主动让出控制权。asyncio
, Go goroutine
, C++20 coroutine
, Rust async/await
。纤程 (Fiber)