iT邦幫忙

2026 iThome 鐵人賽

DAY 12
0
IT Operation

解構作業系統:30 天從 Process、Concurrency 到 Virtual Memory系列 第 12 篇

Day 12|Spinlock:為什麼明知道浪費 CPU,Kernel 還是要一直 Spin?

  • 分享至 

  • xImage
  •  

前兩天我們已經認識了兩種 Synchronization Mechanism:
Mutex / Semaphore
但是還有另一種 Lock,它的想法完全不同:
Thread B:
鎖好了嗎?
鎖好了嗎?
鎖好了嗎?
鎖好了嗎?
鎖好了嗎?
...它不睡覺。甚至一直佔著 CPU 等。
這就是:

Spinlock

但問題來了:
既然 Busy Waiting 會浪費 CPU,為什麼 Linux Kernel 這類系統底層仍然需要 Spinlock?
答案跟「等待到底有多短」以及「睡眠本身也是有成本的」有很大的關係。


1. Spinlock 是什麼?

Spin 就是:Thread / CPU 不斷重複檢查 Lock 是否已經可以取得。
假設:
Thread A
│
│ acquire
▼
Spinlock
│
▼
Critical Section
這時 Thread B 也想取得同一把 Spinlock:
Thread B
│
│ acquire
▼
發現 Spinlock 已被 A 持有 B 不會立刻:Running ->Sleeping
而是:Check Lock
↓
Locked
↓
Check Again
↓
Locked
↓
Check Again
↓
Locked
↓
...

這就是:Busy Waiting
因為 B 仍然在 CPU 上執行 Instructions。


2. 既然 Spin 很浪費,為什麼不乾脆全部 Sleep?

讓一條 Thread 睡著,再把它叫醒,也不是免費的。
假設 Thread B 拿不到 Mutex,系統可能需要讓 B 從 Running 轉成等待狀態:Running -> Blocked / Waiting
接著 Scheduler 可以安排其他工作:CPU
Thread B
│
│ Block
▼
Thread C

等 Lock 可以取得時,又需要:Thread B
Waiting
↓
Ready
↓
Scheduler 選到它
↓
Running

整個過程可能涉及:

  • Thread State Change
  • Scheduler
  • Wakeup
  • Context Switch
    相關的 Cache / Scheduling Cost

也就是:
Sleep 並不是按下一個免費的暫停鍵。
為了避免浪費幾個 CPU cycles,反而付出了更大的 Block / Wakeup / Scheduling 成本。

所以另一種想法就是,B:我先不要睡。

反正 A 應該馬上就好了,我在這裡 Spin 一下。
那 Spin 反而可能比較划算。


3. Spinlock 為什麼特別和 Multi-core 有關?

假設只有:One CPU Core
Thread A:取得 Spinlock
↓
進入 Critical Section

接著某種情況下 CPU 去執行 Thread B,B 發現:
Spinlock 被 A 持有,於是開始:
Spin
Spin
Spin
Spin
Spin
假設現在:
Core 1 → Thread A
Core 2 → Thread B

A 持有 Spinlock,同一時間:
Core 2:
Thread B
│
▼
Spin
Spin
Spin
│
│ A unlock
▼
取得 Lock

就合理很多。因為 B 在 Core 2 上 Spin 的同時:
持有 Lock 的 A 仍然可以在 Core 1 上繼續執行,最後釋放 Lock。


今天的結論

(1)Spinlock 最核心的行為:

想取得 Lock
     │
     ▼
成功了嗎?
 │        │
Yes       No
 │        │
 ▼        ▼
進入      Spin
Critical   │
Section    │
           └────► 再試一次

(2)它和 Mutex 最大的直觀差異在於:

  • Mutex
    拿不到 → 可以 Block

  • Spinlock
    拿不到 → Busy Waiting

Spinlock 的代價非常明顯:等待期間仍然消耗 CPU

(3)它存在的原因:
Critical Section 很短
+
Lock 預期很快釋放
+
Sleep / Wakeup 本身有成本
+
某些 Kernel Context 不能 Sleep
↓
Spin 可能比 Block 更合理

從 Day 8 到現在,其實已經形成一條很完整的 Synchronization 路線:

Race Condition
      ↓
Atomicity
      ↓
Mutex
      ↓
Semaphore
      ↓
Spinlock

但到目前為止,我們一直假設:
只要大家乖乖使用 Lock,事情就會變安全,但是,Lock 本身也能把程式搞死,假設:
A 在等 B。
B 也在等 A。
兩個都沒有辦法繼續,就是卡在那裡了。

下一篇:

Day 13|Deadlock:為什麼大家都拿到 Lock,程式反而永遠動不了?


上一篇
Day 11|Semaphore:如果資源不只一份,要怎麼管理?
下一篇
Day 13|Deadlock:為什麼大家都拿到 Lock,程式反而永遠動不了?
系列文
解構作業系統:30 天從 Process、Concurrency 到 Virtual Memory 共 16 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言