目錄
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-1Daemon 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