- 机密档案室:临界资源。
- 你 (进程):需要进入档案室查阅资料。
- 硬件指令:由档案室中央安保系统提供的、不可分割的"黑科技"操作。
1. 中断屏蔽方法 (Interrupt Masking) - "拉下电闸,与世隔绝"
这是最简单粗暴的一种方法,就像你为了不被打扰,直接冲到大楼配电箱,把整个办公室的电闸给拉了!
-
工作方式:
- 关中断 (Disable Interrupts):在你进入"档案室"之前,你先执行一条特殊指令,告诉中央系统:"接下来谁也别打扰我!所有电话、门铃(中断信号)都暂时屏蔽掉!"
- 访问临界区:现在,因为所有中断都被屏蔽了,CPU 不会因为任何外部事件(如时钟中断、I/O完成)而切换到其他进程。你可以安安心心地在档案室里查资料。
- 开中断 (Enable Interrupts):你从档案室出来后,再执行一条指令,把系统恢复正常,重新接收所有信号。
-
优点:
- 简单高效:逻辑非常清晰,实现起来就两条指令,没有复杂的判断,速度很快。
-
缺点:
- 只适用于单CPU系统:在多CPU环境下,你关掉了自己这个CPU的中断,但无法阻止另一个CPU上的进程也想进入档案室。这个方法管不住别人。
- 滥用风险大 :关中断的权力太大了。如果一个普通的用户程序被允许使用这个指令,它万一忘了开中断,整个系统就"瘫痪"了,无法响应任何外部事件。所以,这必须是特权指令,只有操作系统内核自己能用。
- 临界区过长会出问题:如果档案室里的活儿要干很久,长时间关中断会导致系统对紧急事件的响应延迟,可能会丢失重要的I/O数据。
一句话总结:简单粗暴但有效(在特定场景下),但权力过大,限制很多。
2. TestAndSet (TS/TSL) 指令 - "一边测试状态,一边上锁"的原子操作
这个方法更智能。档案室的门上有一个特殊的电子锁。你不能直接看它的状态,而是要通过一个特殊的按钮来操作它。
-
工作方式:
- 有一个共享的布尔变量
lock
,false
表示门开着,true
表示门锁着。 - TestAndSet 指令 :这是一个由硬件保证的"原子操作",它内部包含了两步,但执行时绝对不会被打断: a. 测试并记录 :它先偷偷看一下
lock
当前的状态(是true
还是false
),并把这个状态记下来。 b. 强制上锁 :不管lock
原来是什么状态,它都立刻把lock
设为true
。 c. 最后,它会返回 它在第一步里记下的那个原始状态。
- 有一个共享的布尔变量
-
使用流程:
- 你想进档案室,就去按那个 TestAndSet 按钮。
- 指令返回了一个值。你检查这个返回值:
- 如果返回的是
false
:这说明在你按按钮之前,门是开着的。虽然现在门已经被你锁上了,但你是第一个锁上它的人,所以你可以进去。 - 如果返回的是
true
:这说明在你按按钮之前,门就已经被别人锁上了。你只能继续在门口循环按按钮(循环等待),直到某一次返回false
为止。
- 如果返回的是
- 用完出来后,你直接把
lock
设为false
,把门打开。
-
优点:
- 实现简洁:上锁的逻辑被封装在一个硬件指令里,代码实现很简单。
- 适用于多CPU环境:因为 TestAndSet 是原子操作,多个CPU上的进程同时执行它,硬件能保证它们会排成一个队,一个一个地完成这个操作,不会出现冲突。
-
缺点:
- 不满足"让权等待" :当一个进程发现门是锁着的(返回
true
),它会在一个while
循环里不停地按按钮(执行TestAndSet指令),这是一种"忙等待",会持续消耗CPU资源。
- 不满足"让权等待" :当一个进程发现门是锁着的(返回
一句话总结:一种优雅且适用于多CPU的硬件锁,但存在忙等待问题。
3. Swap (或 Exchange) 指令 - "用我的钥匙去换门上的钥匙"
这个方法和 TestAndSet 非常相似,只是实现细节不同。可以想象成,每个人手里都有一把钥匙,门上本身也挂着一把。
-
工作方式:
- 有一个共享的布尔变量
lock
,true
表示门锁着。 - 每个想进门的进程,自己手里也准备一个布尔变量
key
,初始设为true
。 - Swap 指令 :这也是一个原子操作,它的功能是交换两个变量的值。比如
swap(a, b)
,执行后 a 的值变成原来 b 的值,b 的值变成原来 a 的值。
- 有一个共享的布尔变量
-
使用流程:
- 你想进档案室,你手里拿着一把值为
true
的key
。 - 你执行
swap(key, lock)
,把你手里的key
和门上的lock
进行了交换。 - 交换后,你检查一下你手里现在拿着的
key
(也就是原来门上的lock
)是什么值:- 如果现在
key
的值是false
:这说明原来门是开着的。你成功地把一把值为true
的钥匙换到了门上(锁上了门),而你换回了一把值为false
的钥匙。你可以进去了。 - 如果现在
key
的值是true
:这说明原来门就是锁着的。你用一把值为true
的钥匙换回了另一把值为true
的钥匙。门还是锁着,你手里还是true
。你只能继续循环这个交换过程。
- 如果现在
- 用完出来后,你把
lock
设为false
,把门打开。
- 你想进档案室,你手里拿着一把值为
-
优缺点:
- 和 TestAndSet 指令完全相同。它只是硬件上另一种实现原子性"测试并上锁"的思路。
- 优点:实现简单,适用于多处理机。
- 缺点:不满足"让权等待",存在忙等待。
一句话总结:和 TestAndSet 异曲同工,都是解决多CPU互斥的硬件方案,也都存在忙等待。
必会题与详解
题目一:与软件实现方法(如Peterson算法)相比,硬件实现方法(如TSL、Swap)最主要的优点是什么?它又有什么普遍的缺点?
答案详解:
-
主要优点:
- 适用性广 :硬件实现方法(如TSL、Swap指令)是原子操作,由硬件保证其不可分割性,因此能够有效地应用于多处理机(多CPU)系统,解决了软件方法在多处理机环境下可能因内存访问时序问题而失效的难题。
- 实现简单:对于应用程序员或系统程序员来说,调用一条硬件指令比实现一套复杂的逻辑(如Peterson算法)要简单得多,代码简洁,不易出错。
-
普遍缺点:
- 未能实现"让权等待":这几种硬件方法在进程无法进入临界区时,都会使其陷入一个循环中,不断地测试锁变量(即"忙等待"或"自旋")。这个过程会持续占用CPU时间,造成资源浪费。如果临界区被占用的时间很长,这种忙等待的开销会非常大。
题目二:为什么"中断屏蔽"方法不能用于多处理机系统中的进程互斥?
答案详解:
"中断屏蔽"方法的核心是通过"关中断"指令来阻止当前CPU被其他事件中断,从而防止进程切换,以此来保证临界区代码的原子性执行。
这个机制在多处理机系统中的问题在于,一条关中断
指令通常只对执行该指令的那个CPU核心有效 。它能阻止自己这个CPU发生进程切换,但它无法阻止其他CPU核心上的进程。
举例来说,在一个双核系统中,CPU-0上的进程A执行了关中断
并进入了临界区。与此同时,CPU-1上的进程B也可以正常运行,如果它也想访问同一个临界资源,它完全可以畅通无阻地进入临界区。这样一来,两个CPU上的两个进程就同时进入了临界区,破坏了互斥性。因此,"中断屏蔽"方法无法在多处理机环境下保证进程互斥。