1996 - Linux 2.0 與 SMP(伺服器的入場券)#
案件摘要#
1996 年 6 月 9 日,Linux 2.0 發布——約 780,000 行程式碼,最重要的新功能是 SMP(對稱多處理器)支援。
\[ \text{2.0 之前:單核只能用一顆 CPU} \;\xrightarrow{\text{2.0}}\; \text{多顆 CPU 同時執行核心程式碼}. \]
Linux 從「PC 的玩具」變成「伺服器的候選人」——沒有 SMP,就沒有後來的網頁伺服器霸權。
前因 -- 為什麼會有這個案子#
- Intel Pentium Pro(1995)的多 CPU 主機板普及:工作站與伺服器普遍有 2–4 顆 CPU——單核 Linux 只能用到一顆,其餘閒置——彌補的缺陷:無法利用多處理器。
- SMP 的理論難題:兩顆 CPU 同時進入核心程式碼會競態條件(race condition)——必須用鎖(spinlock)保護共用資料結構。
- Alan Cox 的角色:核心「二號人物」Alan Cox(1993 年起)維護 2.0 的網路與 SMP——1.0→2.0 的穩定性靠他的整合。
線索與推理 -- 2.0 版的技術面貌(1996)#
| 技術 | 2.0 版狀態 | 彌補的缺陷 |
|---|---|---|
| SMP | spinlock 保護核心、多 CPU 並行 | 單 CPU 浪費硬體 |
| 虛擬記憶體 | 重新設計的 VM 子系統 | 1.x 的 swap 策略簡陋 |
| 檔案系統 | ext2 成為標準(1993.1 進入核心) | ext 的效能與可靠性不足 |
| 網路 | 重新設計的 TCP/IP(Alan Cox) | 1.x 網路層不穩定 |
| 其他 | RAID、IP masquerade(NAT 前身)、ISA PnP | 企業級功能缺位 |
C 範例:spinlock 的本質(SMP 的核心難題)#
/* Linux 2.0 風格:spinlock 保護共用資料 */
spinlock_t my_lock = SPIN_LOCK_UNLOCKED;
void update_shared(void) {
spin_lock(&my_lock); /* 有 CPU 持鎖就在此自旋等待 */
/* ... 更新共用資料結構 ... */
spin_unlock(&my_lock); /* 釋放 */
}
Shell 範例:SMP 的實證#
# 2.0 之後:多顆 CPU 並行
$ cat /proc/cpuinfo | grep processor
processor : 0
processor : 1
# 用 nproc(2008,coreutils)看 CPU 數
$ nproc
2
# 讓 make 用所有核心平行編譯——SMP 的日常應用
$ make -j$(nproc)
Python 範例:競態條件與鎖#
import threading
lock = threading.Lock()
counter = 0
def worker():
global counter
for _ in range(100000):
with lock: # 沒有鎖:兩個執行緒同時加,結果錯誤
counter += 1
threads = [threading.Thread(target=worker) for _ in range(2)]
for t in threads: t.start()
for t in threads: t.join()
print(counter) # 200000——有鎖才正確,這就是 SMP 的核心難題
結案 -- 後果與影響#
- 2.2(1999.1):SMP 擴大到 16 CPU、改進 VM 與網路——Linux 正式進入伺服器市場。
- 伺服器霸權的起點:1996–99 年 LAMP(Linux+Apache+MySQL+PHP)堆疊成型——網頁時代的基礎設施。
- spinlock 的演化:2.0 spinlock → 2.6 讀寫鎖/RCU(2003)——鎖的粒度越來越細。
- 歷史教訓:多核時代的作業系統本質是「鎖的藝術」——SMP 讓 Linux 從玩具變武器。
關鍵人物與文獻#
- L. Torvalds:Linux 2.0 (1996)、spinlock 設計。
- A. Cox:2.0 網路與 SMP 整合。
- 相關案件:
1994-Linux1.0與發行版.md、2003-2.6核心革命.md。