02-1. Thread 是什麼

⏱️ 閱讀時間: 8 分鐘 🎯 難度: ⭐ (超級簡單)


🤔 一句話解釋

Thread(執行緒/線程)是 Process 內的輕量級執行單位,共享 Process 的記憶體空間,可以並發執行不同的任務。


🏢 用公司來比喻

Process = 公司

Yoru-Karu Studio(Process)
├─ 辦公室(記憶體空間)
├─ 資源(檔案、網路)
└─ 員工(Threads)

Thread = 員工

Yoru-Karu Studio
├─ 員工 A(Thread 1)→ 處理訂單
├─ 員工 B(Thread 2)→ 接聽電話
├─ 員工 C(Thread 3)→ 更新網站
└─ 員工 D(Thread 4)→ 回覆郵件

所有員工:
  ✅ 共用同一個辦公室(共享記憶體)
  ✅ 共用同一組資源(檔案、資料庫)
  ✅ 可以同時工作(並發)
  ✅ 可以互相溝通(直接存取共享變數)

💻 Thread 的本質

Thread vs Process

Process(進程)
└─ 獨立記憶體空間
   ├─ Thread 1 (主線程)
   ├─ Thread 2
   ├─ Thread 3
   └─ Thread 4

   所有 Thread 共享這個記憶體空間!

記憶體結構

Process 記憶體
├─ Code Segment    ← 所有 Thread 共享
├─ Data Segment    ← 所有 Thread 共享
├─ Heap            ← 所有 Thread 共享
└─ Stack
   ├─ Thread 1 Stack  ← 各自獨立
   ├─ Thread 2 Stack  ← 各自獨立
   └─ Thread 3 Stack  ← 各自獨立

關鍵:

  • ✅ Code, Data, Heap 共享
  • ✅ 每個 Thread 有自己的 Stack

🔍 實際案例

案例 1:創建 Thread

from threading import Thread
import time

def worker(name):
    print(f"Thread {name} 開始工作")
    time.sleep(2)
    print(f"Thread {name} 完成工作")

# 創建 Thread
t1 = Thread(target=worker, args=('A',))
t2 = Thread(target=worker, args=('B',))

# 啟動 Thread
t1.start()
t2.start()

# 等待 Thread 完成
t1.join()
t2.join()

print("所有 Thread 完成")

輸出:

Thread A 開始工作
Thread B 開始工作
(等待 2 秒...)
Thread A 完成工作
Thread B 完成工作
所有 Thread 完成

案例 2:Thread 共享記憶體

from threading import Thread

# 共享變數
counter = 0

def increment():
    global counter
    for _ in range(100000):
        counter += 1

# 創建 2 個 Thread
t1 = Thread(target=increment)
t2 = Thread(target=increment)

t1.start()
t2.start()
t1.join()
t2.join()

print(f"Counter: {counter}")
# 預期:200000
# 實際:可能是 150000(Race Condition!)

問題:

  • 兩個 Thread 同時修改 counter
  • 可能產生 Race Condition
  • 👉 需要同步機制(Lock)

案例 3:多 Thread 下載檔案

from threading import Thread
import requests

def download(url, filename):
    print(f"下載 {filename}...")
    response = requests.get(url)
    with open(filename, 'wb') as f:
        f.write(response.content)
    print(f"{filename} 下載完成")

urls = [
    ('https://example.com/file1.pdf', 'file1.pdf'),
    ('https://example.com/file2.pdf', 'file2.pdf'),
    ('https://example.com/file3.pdf', 'file3.pdf'),
]

# 使用 Thread 並發下載
threads = []
for url, filename in urls:
    t = Thread(target=download, args=(url, filename))
    t.start()
    threads.append(t)

# 等待所有下載完成
for t in threads:
    t.join()

print("所有檔案下載完成")

📊 Thread 的特性

1. 輕量級

import time
from threading import Thread

start = time.time()

# 創建 1000 個 Thread
threads = [Thread(target=lambda: None) for _ in range(1000)]

for t in threads:
    t.start()

for t in threads:
    t.join()

print(f"時間: {time.time() - start:.2f} 秒")
# 輸出:時間: 0.15 秒 ← 非常快!

2. 共享記憶體

from threading import Thread

shared_list = []  # 共享資料

def producer():
    for i in range(5):
        shared_list.append(i)
        print(f"生產: {i}")

def consumer():
    while len(shared_list) == 0:
        pass  # 等待資料
    while shared_list:
        item = shared_list.pop(0)
        print(f"消費: {item}")

t1 = Thread(target=producer)
t2 = Thread(target=consumer)

t1.start()
t2.start()
t1.join()
t2.join()

3. 並發執行

from threading import Thread
import time

def task(name, duration):
    print(f"{name} 開始")
    time.sleep(duration)
    print(f"{name} 完成")

# 並發執行
t1 = Thread(target=task, args=('任務 A', 2))
t2 = Thread(target=task, args=('任務 B', 3))

start = time.time()
t1.start()
t2.start()
t1.join()
t2.join()

print(f"總時間: {time.time() - start:.2f} 秒")
# 輸出:總時間: 3.00 秒 ← 並發執行,不是 2+3=5 秒

🎯 Thread 的角色

主 Thread(Main Thread)

from threading import Thread, current_thread

def worker():
    print(f"工作 Thread: {current_thread().name}")

# 主 Thread
print(f"主 Thread: {current_thread().name}")

# 創建新 Thread
t = Thread(target=worker)
t.start()
t.join()

輸出:

主 Thread: MainThread
工作 Thread: Thread-1

Daemon Thread(背景 Thread)

from threading import Thread
import time

def background_task():
    while True:
        print("背景任務執行中...")
        time.sleep(1)

# 設定為 Daemon Thread
t = Thread(target=background_task, daemon=True)
t.start()

time.sleep(3)
print("主 Thread 結束")
# Daemon Thread 會自動終止

✅ 重點回顧

Thread 的定義:

  • Process 內的輕量級執行單位
  • 共享 Process 的記憶體空間
  • 有自己的 Stack

Thread 的特性:

  • ✅ 創建成本低
  • ✅ 共享記憶體
  • ✅ 可以並發執行
  • ✅ 通訊簡單

關鍵理解:

  • ✅ Thread 是 Process 的一部分
  • ✅ 所有 Thread 共享 Code, Data, Heap
  • ✅ 每個 Thread 有獨立的 Stack
  • ✅ 適合 I/O 密集型任務

上一篇: 01-5. Process vs Thread 完整對比 下一篇: 02-2. Thread 的優缺點


最後更新:2025-01-04

0%