跳到正文

2.1.1+2.1.2 进程的概念、组成、特征

32 分钟

“等待 CPU”和“等待 I/O”不是同一种等

组成原理最后讲到中断把控制权交给操作系统。今天任务追踪进程 P:创建后进入就绪,调度后运行,发起磁盘读后阻塞,I/O 完成中断使它回到就绪,再次调度后运行并退出。每次状态变化都必须由合法事件触发。

TRANSITIONS={
    ("new","admit"):"ready",
    ("ready","dispatch"):"running",
    ("running","preempt"):"ready",
    ("running","io_request"):"blocked",
    ("blocked","io_complete"):"ready",
    ("running","exit"):"terminated",
}

def trace_process(events):
    state="new"; trace=[state]
    for event in events:
        key=(state,event)
        if key not in TRANSITIONS: raise ValueError(f"非法转换:{key}")
        state=TRANSITIONS[key]; trace.append(state)
    return trace

events=["admit","dispatch","io_request","io_complete","dispatch","exit"]
assert trace_process(events)==["new","ready","running","blocked","ready","running","terminated"]

手工表中,I/O 请求后 P 不能留在 ready,因为即使立刻给 CPU 它也无法继续;I/O 完成后也不能直接变 running,必须先进入 ready,是否获得 CPU 由调度器决定。时间片到对应 running→ready,而不是 blocked。

为什么正确:状态描述进程当前缺少的资源;ready 只缺 CPU,blocked 等待某事件,running 正占 CPU。转换表把事件与资源条件一一对应,非法事件会被拒绝。

进程拥有独立地址空间和资源,线程共享进程地址空间但各有程序计数器、寄存器和栈。线程切换通常更轻,却也带来共享数据竞争。

模拟 E 个事件时间 O(E)、轨迹空间 O(E)。典型错误:把阻塞唤醒直接画到运行;认为进程能主动从 ready 变 running;混淆用户态/内核态与进程状态——运行进程可因系统调用进入内核态,但仍可能是 running。

迁移答案:若 P 运行中被更高优先级进程抢占,转换是 running→ready;它没有等待外设,不能进入 blocked。

下一课在多个 ready 进程之间真正做选择,并计算周转时间、等待时间和响应时间。

小纸条

学完《2.1.1+2.1.2 进程的概念、组成、特征》后,请独立复现本课的核心状态变化或计算过程。

登录 后可看答案

Practice

本课练习

0

先独立作答再提交;编程题会在隔离沙箱中真实编译、运行并对拍。

本课练习正在补齐,暂不应标记为完成。