上课用到的讲解
王道模拟卷第一套
这是一道非常经典的计算机组成原理题目,考查的是单周期CPU设计中**取指阶段(Instruction Fetch)**的数据通路和控制逻辑。
下面我针对题目中的5个问题逐一进行详细分析和解答。
1) 以上取指部件的输入信号有哪些?各有什么作用?(不考虑时钟信号)
观察图中虚线框(取指部件/下地址逻辑)的边界,找出从外部进入该区域的信号线:
输入信号列表及作用:
Jump(跳转控制信号):- 作用:控制最右侧的多路选择器(MUX)。当
Jump = 1时,选择跳转目标地址(Jump Target)作为下一条指令的地址;当Jump = 0时,选择顺序执行或分支跳转的结果。
- 作用:控制最右侧的多路选择器(MUX)。当
Branch(分支控制信号):- 作用:表示当前指令是否为条件分支指令(如
beq)。它作为与门的一个输入,参与控制中间的多路选择器。
- 作用:表示当前指令是否为条件分支指令(如
Zero(零标志位信号):- 作用:来自ALU(算术逻辑单元)的输出结果。表示比较结果是否为0(例如两数相等时为1)。它与
Branch信号做“与”运算,决定是否满足分支跳转条件。
- 作用:来自ALU(算术逻辑单元)的输出结果。表示比较结果是否为0(例如两数相等时为1)。它与
imm16(16位立即数):- 作用:来自指令的低16位。用于计算分支指令(Branch)的目标地址偏移量。
Target<25:0>(26位目标地址):- 作用:来自指令的低26位。用于生成无条件跳转指令(Jump)的绝对目标地址。
2) 给出以上三种情况下的输入信号,信号有效为1,无效为0
题目要求针对三种情况给出 Jump, Branch, Zero 的值。特别注意:分支指令需要区分“条件满足”和“条件不满足”两种情况。
逻辑分析:
- MUX1 (中间那个):控制信号是
Branch AND Zero。为1时选分支地址,为0时选PC+1。 - MUX2 (右边那个):控制信号是
Jump。为1时选Jump地址,为0时选MUX1的输出。
信号状态表:
| 情况 | Jump | Branch | Zero | 结果分析 |
|---|---|---|---|---|
| 顺序执行指令 | 0 | 0 | 0 (或X) | Jump=0 选下路,Branch=0 导致与门输出0,选 PC+1。注:非分支指令 Branch 必须为0,Zero 此时通常无效,但在题目”无效为0”的要求下填0。 |
| Branch指令 (条件满足) | 0 | 1 | 1 | Jump=0 选下路,Branch=1 且 Zero=1,与门输出1,选 PC+1+Offset。 |
| Branch指令 (条件不满足) | 0 | 1 | 0 | Jump=0 选下路,Branch=1 但 Zero=0,与门输出0,选 PC+1 (即顺序执行)。 |
| Jump指令 | 1 | 0 | 0 (或X) | Jump=1 直接选上路Jump目标。Jump指令不是Branch指令,故 Branch 设为0。 |
(注:对于“无效为0”的要求,表格中Don’t Care的情况都填了0)
3) 为什么在该数据通路中 PC 不需要写“使能”控制信号?
答案:
因为这是单周期 CPU(Single Cycle CPU)。
- 在单周期设计中,每一条指令的执行都刚好占用一个时钟周期。
- 在每一个时钟周期的末尾(通常是时钟上升沿),PC 必须更新,指向下一条指令(无论是顺序的下一条、分支目标还是跳转目标)。
- 并不存在需要保持 PC 值不变跨越多个周期的情况(不像多周期CPU或流水线中遇到冒险时需要冻结PC),因此不需要“写使能”信号来控制是否写入,而是每个时钟沿都会无条件写入新的值。
4) 对于无条件跳转指令,当前可跳转的最大和最小地址之间共包含多少条指令?
分析:
- Jump 指令的目标地址计算公式为:
PC_new<31:2> = PC_old<31:28> || Target<25:0>。 - 其中高4位由当前PC决定,这意味着跳转范围被限制在当前的 256MB ($2^{28}$ 字节) 区域内。
- 在这个区域内,具体的地址由指令中的 26位
Target字段决定。 - 题目问的是“包含多少条指令”。由于指令是字对齐的(4字节一条),且 PC 中存储的是 字地址(即题目中的
PC<31:2>),26位的Target直接对应了指令的索引。 - 这26位可以从全0变化到全1。
计算:
- 变化范围是 26位二进制数。
- 包含的指令数 = $2^{26}$。
- 数值计算:$2^{26} = 2^6 \times 2^{20} = 64 \text{ M}$ (64兆)。
答案:
共包含 $2^{26}$ 条指令(或者写 64M 条指令)。
5) 图中的 SignExt 部件起什么作用?
答案:SignExt 是符号扩展单元(Sign Extender)。
- 作用:它将指令中的 16位立即数(imm16) 扩展为 30位(根据题目PC位宽为30位),以匹配加法器的输入位宽。
- 目的:在计算分支跳转地址时(
PC + Offset),偏移量(Offset)通常是有符号数(可以向前跳转也可以向后跳转)。符号扩展能够保留原始数据的正负号(即把16位数的最高位复制填充到高位),从而保证加法运算后的地址计算结果是正确的。
这是一个非常经典的操作系统 PV操作(信号量机制) 题目,属于“生产者-消费者”问题的变种。
这个问题的核心难点在于:除了常规的互斥访问仓库和消费者同步外,还需要处理两个生产者之间的 数量制约关系。
下面我将分步为你解析并给出解答。
1. 题目分析与信号量定义
我们需要解决三个层面的同步/互斥问题:
第一层:仓库的互斥访问
题目要求“不允许同时入库,也不允许边入库边出库”。
- 这意味着 A、B、C 三个进程对仓库的访问是互斥的。
- 信号量:
mutex,初值为 1。
第二层:消费者与生产者的同步
消费者 C 需要等待仓库里有货才能取。
- 因为仓库是“无限大”的,所以生产者 A 和 B 不需要等待“空位”,但消费者 C 需要等待“产品”。
- 信号量:
full(或 count),初值为 0,代表仓库中当前产品的数量。
第三层:生产者 A 和 B 之间的制约关系(核心难点)
题目给出的公式是:$-n \le (A\text{的件数} - B\text{的件数}) \le m$。
这其实包含两个不等式,我们需要分别设置信号量来控制。
不等式 1: $A - B \le m \Rightarrow A \le B + m$
- 这意味着:A 的产量不能比 B 多超过 $m$ 个。
- 换句话说,A 想生产,需要消耗一个“允许 A 领先的额度”。这个额度由 B 生产来补充。初始额度为 $m$。
- 信号量:
Sa,初值为 $m$。 - 操作: A 生产前
P(Sa),B 生产后V(Sa)。
不等式 2: $-n \le A - B \Rightarrow B - A \le n \Rightarrow B \le A + n$
- 这意味着:B 的产量不能比 A 多超过 $n$ 个。
- 换句话说,B 想生产,需要消耗一个“允许 B 领先的额度”。这个额度由 A 生产来补充。初始额度为 $n$。
- 信号量:
Sb,初值为 $n$。 - 操作: B 生产前
P(Sb),A 生产后V(Sb)。
2. 信号量设置总结
1 | |
3. 进程工作流程代码
下面是 A、B、C 三个进程的伪代码逻辑:
生产者进程 A
A 进程生产 A 产品。它受到“A不能比B多太多”的限制,同时它的生产会解除“B不能比A多太多”的限制。
1 | |
生产者进程 B
B 进程生产 B 产品。它受到“B不能比A多太多”的限制,同时它的生产会解除“A不能比B多太多”的限制。
1 | |
消费者进程 C
C 进程只负责取货,它不需要关心 A 和 B 的数量差(题目说“对仓库中产品A和B的件数无上述要求”),它只关心有没有货。
1 | |
4. 关键点解说(为什么这样写是对的?)
- 互斥锁的位置:
P(mutex)和V(mutex)必须紧紧包裹住“入库”和“出库”的动作,不能把 P(Sa) 或 P(Sb) 包进去,否则可能导致死锁(例如 A 占了 mutex 但因为 Sa 不足而阻塞,B 想要生产增加 Sa 却进不去 mutex)。 - 交叉唤醒:
- A 生产后执行
V(Sb):因为 $B-A \le n$,当 $A$ 增大,$B$ 能够合法生产的数量就增加了。 - B 生产后执行
V(Sa):因为 $A-B \le m$,当 $B$ 增大,$A$ 能够合法生产的数量就增加了。
- A 生产后执行
- 消费者的无关性:题目特意强调“对仓库中产品 A 和 B 的件数无上述要求”。这意味着消费者取走 A 还是取走 B,都不会影响“A 总生产数”和“B 总生产数”之间的差值关系。因此,消费者 C 不需要操作 Sa 或 Sb。
这是一个关于操作系统内存管理(分页机制)的计算题,主要考查了多级页表、大页(4MB页)与普通页(4KB页)混合管理、地址转换以及页面置换算法。
下面是简洁的步骤解析:
1) 访存次数分析
- 013FF35AH:
- 将十六进制转为二进制,高10位是
0000 0001 00(即索引 4H)。 - 查表得索引
4H的Page_Size为 0,说明是 4KB页。 - 4KB页采用二级分页,访存路径为:①访问页目录 $\rightarrow$ ②访问二级页表 $\rightarrow$ ③访问目标数据。
- 结论:至少需要 3 次访存。
- 将十六进制转为二进制,高10位是
- 015F123DH:
- 高10位是
0000 0001 01(即索引 5H)。 - 查表得索引
5H的Page_Size为 1,说明是 4MB页。 - 4MB页采用一级分页(绕过内层页表),访存路径为:①访问页目录 $\rightarrow$ ②访问目标数据。
- 结论:至少需要 2 次访存。
- 高10位是
2) 地址转换与页框大小
- 虚拟地址:
015F123DH - 页框大小:根据上题分析,索引
5H对应的Page_Size=1,所以页框大小是 4MB。 - 物理地址计算:
- 对于4MB大页,逻辑地址的高10位是页号,低22位是页内偏移。
- 页内偏移:
015F123DH的低22位。015Hex =0000 0001 0101Bin。- 去掉高10位(
0000 0001 01),剩下的高位部分是01(二进制)。 - 拼接剩下的
F123DH,偏移量部分为1F123DH。
- 页框基址:表中索引
5H对应的页框号是163H。对于4MB页,物理基址 = 页框号 $\times$ 4MB (即左移22位)。 - 拼接/计算:
- 物理地址高10位由
163H提供,低22位由偏移量提供。 163H=01 0110 0011(二进制)- 拼接
01 1111 0001 0010 0011 1101(偏移量) - 组合二进制:
0101 1000 1101 1111 0001 0010 0011 1101 - 转十六进制:58DF123DH
- 物理地址高10位由
3) FIFO置换后的物理地址
- 分配策略:该进程有两个4KB页框和两个4MB页框。
- 当前状态:我们需要访问
00D40866H(高10位是0H0HD…即0000 0000 11-> 索引 3H)。 - 缺页分析:表项
3H的Valid位为0,且Page_Size为1(4MB页),发生缺页。 - 置换选择 (FIFO):
- 我们需要在已有的有效4MB页中选择一个淘汰。
- 查看表中有效的4MB页(
Valid=1且Page_Size=1):- 索引 2H:装入时刻 180
- 索引 5H:装入时刻 300
- 180 < 300,索引 2H 最早装入,被淘汰。
- 新页面(3H)将使用被淘汰页面(2H)的物理页框,即页框号 254H。
- 物理地址计算:
- 虚拟地址
00D40866H。 - 偏移量(低22位):
D是1101,去掉高2位(属于页号),剩01,后接40866。即偏移量140866H。 - 新页框号:
254H。 - 拼接:
254H=10 0101 0100140866H=01 0100 0000 1000 0110 0110- 组合:
1001 0101 0101 0100 0000 1000 0110 0110
- 结果:95540866H
- 虚拟地址
4) 页目录表项的物理地址
题目问的是**“本次更新的页目录表项的物理地址”**,也就是指向该页表项本身的指针地址,而不是缺页数据的物理地址。
- 虚拟地址:
2EBCA234H - 页目录索引:
2EB...=0010 1110 1011...- 高10位为
0010 1110 10= 0BAH。
- 计算公式:页目录表项物理地址 = 页目录基址 (PDBR) + (索引 $\times$ 表项大小)
- 数据代入:
- PDBR =
7F65 4000H - 索引偏移 =
BAH$\times$ 4字节 BAH= 186 (十进制) $\rightarrow$ $186 \times 4 = 744$ = 2E8H
- PDBR =
- 最终结果:
7F65 4000H+2E8H= 7F65 42E8H
这是一道非常经典的计算机组成原理题目,考查的是数据的机器级表示、二进制算术运算以及**标志位(Condition Codes)**的生成机制。
题目背景明确指出:字长8位,无符号整数(Unsigned Integer),$x=68, y=80$。
以下是针对这5个小问的详细解析:
1) 寄存器 A 和 B 中的内容分别是什么?
我们需要将十进制数转换为8位的十六进制数。
- x = 68
- 计算:$68 = 4 \times 16 + 4$
- 十六进制:44H
- 二进制验证:$0100\ 0100_2$
- y = 80
- 计算:$80 = 5 \times 16 + 0$
- 十六进制:50H
- 二进制验证:$0101\ 0000_2$
答案:
- 寄存器 A 中的内容:44H
- 寄存器 B 中的内容:50H
2) 若 $x$ 和 $y$ 相加,寄存器 C 内容?结果是否正确?Cout?ZF?CF?
执行运算:$x + y$ 即 $44H + 50H$。
- 计算过程:
1
2
3
40100 0100 (44H, 十进制68)
+ 0101 0000 (50H, 十进制80)
-----------
1001 0100 (94H, 十进制148) - 结果分析:
- 内容:$94H$。
- 正确性:无符号数范围是 $0 \sim 255$ ($2^8-1$)。$68 + 80 = 148$,没有超出范围,所以结果正确。
- Cout (最高位进位):最高位(第7位)计算是 $0+0=0$,没有产生进位,所以 $Cout = 0$。
- ZF (零标志):结果是 $94H$(不为0),所以 $ZF = 0$。
- CF (进位标志):在加法中,无符号数的溢出由 CF 表示,且 $CF = Cout$。因为没有进位,所以 $CF = 0$。
答案:
- 寄存器 C 的内容:94H
- 运算结果是否正确:正确
- Cout:0
- ZF:0
- CF:0
3) 若 $x$ 和 $y$ 相减,寄存器 D 内容?结果是否正确?Cout?ZF?CF?
执行运算:$x - y$。在计算机底层,减法通常通过加补码来实现,即 $A - B = A + (\sim B + 1)$(这里的 $\sim B$ 指按位取反)。
- 计算过程:
- $y = 50H (0101\ 0000)$
- $-y$ 的机器数(补码形式) = $1010\ 1111 + 1 = 1011\ 0000$ (B0H)
- 执行加法:$44H + B0H$
1
2
3
40100 0100 (44H)
+ 1011 0000 (B0H)
-----------
1111 0100 (F4H) - 结果分析:
- 内容:$1111\ 0100$ 即 F4H。
- 正确性:十进制实际上是 $68 - 80 = -12$。但是这是无符号数运算,无符号数不能表示负数。结果 $F4H$ 对应十进制 $244$,这显然不是 $-12$。发生了借位(Underflow),所以结果不正确。
- Cout (最高位进位):最高位计算 $0+1=1$,没有产生向更高位的进位(即没有进位输出),所以 $Cout = 0$。
- ZF (零标志):结果 $F4H \neq 0$,所以 $ZF = 0$。
- CF (进位/借位标志):
- 在减法中,CF 表示借位。
- 逻辑判断:因为 $x < y$ ($68 < 80$),不够减,必然发生借位,所以 $CF = 1$。
- 硬件关系:在大多数处理器(如x86、常见教材模型)中,减法的 $CF$ 标志通常定义为 $CF = \text{Cout} \oplus 1$(即 Cout 取反)。因为加法器做减法时没有产生进位($Cout=0$),说明不够减,需要“借位”,因此 $CF = 1$。
答案:
- 寄存器 D 的内容:F4H
- 运算结果是否正确:不正确(发生了下溢)
- Cout:0
- ZF:0
- CF:1
4) Cout 的含义是什么?它与 CF 标志的关系是什么?
这是一个考察底层原理的问题。
答案:
- Cout 的含义:$Cout$ 是加法器(ALU)最高位(MSB)运算后产生的物理进位输出信号。它仅表示最高位是否向更高位进位。
- 与 CF 标志的关系:
- 执行加法时:$CF = Cout$。即如果最高位有进位,说明无符号数加法溢出(结果太大,超过了255)。
- 执行减法时:$CF = \overline{Cout}$ (Cout 取反)或者说 $CF = 1 - Cout$。
- 减法是通过“加补码”实现的。
- 如果 $A - B$ 过程中 $Cout=1$,说明 $A \ge B$,没有借位,此时 $CF=0$。
- 如果 $A - B$ 过程中 $Cout=0$,说明 $A < B$,需要借位,此时 $CF=1$。
5) 无符号整数通常用来表示什么?为什么通常不对无符号整数的运算结果判断溢出?
这里需要区分“溢出标志 OF (Overflow Flag)”和“进位标志 CF (Carry Flag)”。
答案:
- 用途:无符号整数通常用来表示内存地址、索引、计数器、或者图像像素值等只有非负值的物理量。
- 为什么不判断“溢出”(指OF标志):
- 概念区分:在计算机术语中,“溢出(Overflow, OF标志)”专门指**带符号整数(Signed Integer)**运算结果超出了补码能表示的范围(破坏了符号位)。
- 无符号数的特性:无符号数没有符号位,所有位都是数值位。
- 判断依据:对于无符号数,结果超出范围(比如超过255或低于0)是由**进位标志(CF)**来指示的,而不是由溢出标志(OF)来指示的。因此,我们关注的是 CF,而不是 OF。
这是一道非常经典的计算机组成原理题目,主要考察的是MIPS指令格式、大立即数的构建以及符号扩展带来的影响。
下面我分步为你详细解析这三个问题。
第一问:立即数位数与为何不能直接送入
问题分析:
立即数占多少位?
观察代码中的lui(Load Upper Immediate)和ori(Or Immediate)指令。题目设定 $A$ 是32位地址,被分成了 $A_upper$ 和 $A_lower$ 两个16位的部分。lui指令加载的是 $A_upper$(16位)。ori指令操作的是 $A_lower$(16位)。- 结论:该指令系统(通常指MIPS)中的立即数占 16 位。
为什么不能直接将 32 位地址 $A$ 送入寄存器?
这是由指令字长决定的。- 在标准的 32 位指令集(如 MIPS)中,一条指令的总长度固定为 32 位。
- 一条指令通常包含操作码(Opcode)、目标寄存器、源寄存器等字段。如果想在指令中直接包含一个 32 位的立即数(地址),那么光这一个数就占满了 32 位,完全没有空间去放操作码和寄存器编号了。
- 结论:因此,必须将 32 位的大常数拆分成两个 16 位的部分,分两次加载。
答案总结:
- 立即数占 16 位。
- 因为一条指令的总长度有限(通常为32位),无法在一条指令中同时容纳操作码、寄存器地址和完整的32位立即数,所以需要分两次操作来合成32位地址。
第二问:填空与操作解释
代码逻辑分析:
lui t0, A_upper:它的功能是将 16 位立即数 $A_upper$ 放到寄存器t0的高 16 位,并将低 16 位清零。- 题目注释:“将A_upper 的 (①) 添加16个0”。因为数据放到了高位,所以是在低位补了0。
ori t0, t0, A_lower:它的功能是将t0与 16 位立即数 $A_lower$ 进行“或”运算。- 在进行逻辑运算时,16位立即数通常进行无符号扩展(Zero Extension),即高 16 位补 0。
- 题目注释:“将A_lower 的 (②) 添加16个0”。因为是无符号扩展,所以是在高位补了0。
lui之后,t0的状态是[A_upper][0000]。ori的立即数扩展后是[0000][A_lower]。- 执行**“或”(OR)**操作:
[A_upper][0000]OR[0000][A_lower]=[A_upper][A_lower]。这正是我们想要的拼接效果。
答案总结:
- ① 低位:
lui把立即数移到高位,低位补0。 - ② 高位:
ori对立即数进行零扩展(Zero Extension),高位补0。 - ③ “或”:通过逻辑或运算将高位部分和低位部分拼合在一起。
第三问:A_upper_adjusted 的计算 (核心难点)
问题背景:
第二种方法使用指令 lw s0, A_lower(t0)。
这条指令的执行过程是:Effective_Address = Reg[t0] + SignExtend(A_lower)。
关键在于 SignExtend(符号扩展)。
原理解析:
- 符号扩展的陷阱:
lw指令在计算地址时,会将 16 位的偏移量($A_lower$)视为有符号数,并进行符号扩展至 32 位,然后再与基址寄存器(t0)相加。 - 分类讨论:
- 情况 1:$A_lower$ 的最高位(第15位)是 0。
- 符号扩展后,高 16 位全是 0。
- 加法运算:
Address = (A_upper << 16) + A_lower。 - 此时无需调整,
A_upper_adjusted = A_upper。
- 情况 2:$A_lower$ 的最高位(第15位)是 1。
- 符号扩展后,高 16 位全是 1(即
0xFFFF)。这意味着 $A_lower$ 被当成了一个负数。 - 例如:如果 $A_lower$ 是
0x8000,符号扩展后变成0xFFFF8000。 - 此时如果直接相加:
Total = (A_upper << 16) + 0xFFFF8000。 - 注意
0xFFFF8000其实等于-0x8000(如果视作整体32位偏移) 或者理解为它向高位“借了1”。 - 实际上,加法会使得高 16 位的值减 1。
- 修正方法:为了抵消这个“减 1”的影响,我们需要预先在 $A_upper$ 上 加 1。
- 符号扩展后,高 16 位全是 1(即
- 情况 1:$A_lower$ 的最高位(第15位)是 0。
答案总结:
- 计算方法:
- 若 $A_lower$ 的最高位为 0,则
A_upper_adjusted = A_upper。 - 若 $A_lower$ 的最高位为 1,则
A_upper_adjusted = A_upper + 1。
- 若 $A_lower$ 的最高位为 0,则
- 理由:
lw指令在计算有效地址时,会对 16 位偏移量 $A_lower$ 进行符号扩展。
如果 $A_lower$ 的最高位为 1,符号扩展会使其对应的高 16 位全为 1(相当于从高位借位/减去了一个高位的1)。为了补偿这个借位,必须预先将高位地址 $A_upper$ 加 1,以保证最终计算出的物理地址正确。
这是一个经典的**多生产者-单消费者(Producer-Consumer)**问题的变种。
这个问题的核心在于处理资源的数量限制(缓冲区大小)和配对关系(1个A配3个B)。我们需要用信号量来控制缓冲区是否已满(生产者等待)以及缓冲区是否有足够的零件(消费者/装配线等待)。
下面是详细的解答:
1. 信号量定义 (Semaphore Definition)
我们需要定义两类信号量:
- 同步信号量(表示资源数量): 用来告诉装配线现在有多少个零件A和零件B。
- 资源限额信号量(表示缓冲区空位): 用来限制生产者的生产,防止堆积超过题目要求的上限(A最多1个,B最多3个)。
1 | |
2. 进程工作流程 (Process Logic)
题目中有三类进程:零件A生产线(1个)、零件B生产线(3个)、装配生产线(1个)。
(1) 零件A生产线进程 (Producer A)
它的逻辑是:看A区有没有空位 -> 有空位则放入 -> 告诉装配线A来了。
1 | |
(2) 零件B生产线进程 (Producer B)
共有3条这样的生产线,逻辑相同。它的逻辑是:看B区有没有空位 -> 有空位则放入 -> 告诉装配线B来了。
1 | |
(3) 装配生产线进程 (Assembler)
它的逻辑是:等待集齐1个A和3个B -> 取走零件进行组装 -> 释放空位给生产者(激活生产者)。
1 | |
3. 代码注解与逻辑分析
关于
P(empty_A)和P(empty_B):- 题目规定“若已有1个A在等待,A生产线需等待”,这正是
empty_A初值设为1的作用。当A生产了一个并执行P后,empty_A变为0。如果它再生产一个想放入,再次执行P时就会阻塞,直到装配线取走原来的A并执行V(empty_A)。 - 同理,
empty_B初值为3,允许缓冲区最多堆积3个B。
- 题目规定“若已有1个A在等待,A生产线需等待”,这正是
关于装配线的
P操作:- 装配线需要 1个A 和 3个B。因此它必须执行一次
P(full_A)和 三次P(full_B)。只有当这四个条件都满足时(即仓库里确实有货),它才能进行组装。如果货不够,装配线就会阻塞在相应的P操作上。
- 装配线需要 1个A 和 3个B。因此它必须执行一次
关于装配线的
V操作:- 题目要求“然后激活等待的其他零件生产线”。
- 当装配完成后,实际上是把缓冲区里的零件取走了(清空了)。
- 执行
V(empty_A)会让empty_A+ 1,如果此时 Producer_A 正在阻塞,它就会被唤醒。 - 同理,需要连续执行三次
V(empty_B),把占用的3个B的名额全部释放出来,这样如果有被阻塞的 B 生产线,它们就能继续送入零件。