第27天:多線程與多進程
課程簡介
在 Python 中,為了提升程式的運行效率,特別是針對 I/O 密集型和 CPU 密集型任務,可以使用多線程與多進程來進行並行或並發處理。今天的課程將介紹 Python 中的多線程和多進程概念,並學習如何使用標準庫中的 threading
和 multiprocessing
模組。
學習內容
1. 多線程(Multithreading)
多線程適用於 I/O 密集型任務,例如檔案讀寫、網絡請求等。Python 提供了 threading
模組來實現多線程。
1.1 創建線程
可以使用 threading.Thread
類來創建一個新線程。
範例:
1
2
3
4
5
6
7
8
9
10
11
12
13
import threading
import time
# 定義一個任務函數
def task():
print("任務開始")
time.sleep(2)
print("任務結束")
# 創建並啟動線程
thread = threading.Thread(target=task)
thread.start()
thread.join() # 等待線程執行完畢
1.2 使用多個線程
可以同時創建多個線程來執行任務。
範例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 定義任務
def print_numbers():
for i in range(5):
print(i)
time.sleep(1)
# 創建多個線程
threads = [threading.Thread(target=print_numbers) for _ in range(3)]
# 啟動並等待所有線程完成
for t in threads:
t.start()
for t in threads:
t.join()
1.3 使用鎖(Lock)
當多個線程需要訪問共享資源時,為避免資源競爭,應使用鎖來確保執行的安全性。
範例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
lock = threading.Lock()
counter = 0
def increase():
global counter
with lock: # 使用鎖
local_counter = counter
time.sleep(0.1)
counter = local_counter + 1
print(counter)
# 創建並啟動線程
threads = [threading.Thread(target=increase) for _ in range(5)]
for t in threads:
t.start()
for t in threads:
t.join()
2. 多進程(Multiprocessing)
多進程適用於 CPU 密集型任務,例如大量的數據計算。Python 的 multiprocessing
模組可以創建多個進程來分配不同的 CPU 核心。
2.1 創建進程
使用 multiprocessing.Process
類創建一個新進程。
範例:
1
2
3
4
5
6
7
8
9
10
11
from multiprocessing import Process
def process_task():
print("進程開始")
time.sleep(2)
print("進程結束")
# 創建並啟動進程
process = Process(target=process_task)
process.start()
process.join() # 等待進程完成
2.2 使用多個進程
可以創建多個進程來並行執行不同的任務。
範例:
1
2
3
4
5
6
7
8
9
10
11
12
# 定義任務
def calculate_square(n):
print(f"{n} 的平方為 {n ** 2}")
# 創建多個進程
processes = [Process(target=calculate_square, args=(i,)) for i in range(5)]
# 啟動並等待所有進程完成
for p in processes:
p.start()
for p in processes:
p.join()
2.3 使用進程池(Pool)
當需要大量進程時,可以使用進程池來管理進程並限制同時運行的進程數。
範例:
1
2
3
4
5
6
7
8
from multiprocessing import Pool
def cube(n):
return n ** 3
with Pool(3) as pool: # 同時執行 3 個進程
results = pool.map(cube, range(10))
print(results)
3. 多線程與多進程的選擇
- I/O 密集型任務:多線程適用於需要頻繁進行 I/O 操作的任務,如讀取檔案、處理網絡請求。
- CPU 密集型任務:多進程適用於需要大量計算的任務,可充分利用多核心處理器。
4. GIL(全局解釋器鎖)
Python 的 GIL 限制了多線程在同一時間只能有一個線程執行 Python bytecode,因此多線程不適合 CPU 密集型任務。而多進程不受 GIL 限制,適合 CPU 密集型任務。
教學重點
- 多線程的基本操作:理解如何使用
threading
創建與管理線程,以及鎖的使用。 - 多進程的基本操作:掌握如何使用
multiprocessing
創建與管理進程,並利用進程池來優化多進程處理。 - 多線程 vs. 多進程的選擇:理解 GIL 的影響,並選擇適合的並行方式。
- 資源同步:使用鎖來管理多線程間的共享資源,避免競爭條件。
任務
- 使用多線程模擬一個同時處理多個檔案的 I/O 任務。
- 使用多進程計算 1 到 10 的平方並顯示結果。
- 創建一個進程池來並行處理多個數字的立方計算。
本文章以 CC BY 4.0 授權