Python - 多線程
你好,未來的 Python 魔法師們!今天,我們將進入 Python 的多線程世界,展開一段激動人心的旅程。如果你是編程新手,也別擔心;我將成為你友善的嚮導,我們將一步步探索這個主題。所以,拿起你的虛擬魔杖(鍵盤),我們一起深入探險吧!
什麼是多線程?
在我們使用 Python 線程施展魔法之前,先來了解多線程究竟是什麼。想象一下,你是一位在忙碌廚房中的廚師。如果你一個人做飯,一次只能做一件事——切菜、然後燒水、然後煎肉。但是,如果你有許多手能同時做不同的工作呢?這基本上就是多線程為我們的程序所做的!
多線程允許程序在單個進程內同時執行多個任務。這就像有許多廚師(線程)在同一個廚房(進程)中合作準備一頓美味的餐點(程序輸出),使其更快、更有效率。
與進程的比較
現在,你可能在想,“但是老師,我聽過進程也。線程和進程有什麼不同?”這是一個很好的問題!讓我們來解析一下:
-
資源使用:線程就像共用房間的兄弟姊妹(記憶體空間),而進程則像擁有獨立房屋的鄰居。線程較輕量,並共享資源,因此在某些任務上更有效率。
-
通信:線程可以通過共享變量輕鬆交談,但進程需要使用特殊的“電話”(進程間通信)來相互對話。
-
開銷:創建和管理線程通常比進程更快,且需要较少的系統資源。
-
複雜性:雖然線程可以使你的程序運行得更快,但也引入了複雜性。這就像玩雜技——如果做得好,既有趣又有效率,但如果你不小心,可能會失手!
Python 的線程處理模塊
Python 是一種慷慨的語言,為我們提供了多個用於處理線程的模塊。其中兩個主要的是:
-
threading:這是用於處理線程的高階接口。它就像友好的巫師助手一樣,為你完成大部分重活。
-
_thread:這是低階接口。它就像古老的魔法書——強大但需要更多的專業知識才能正確使用。
今天我們的魔法旅程將聚焦於 threading
模塊,因為它對初學者更友好且廣泛使用。
創建新的線程
好的,讓我們施展第一個線程魔法!以下是創建和啟動新線程的方法:
import threading
import time
def print_numbers():
for i in range(5):
time.sleep(1)
print(f"線程 1: {i}")
# 創建一個新的線程
thread1 = threading.Thread(target=print_numbers)
# 啟動線程
thread1.start()
# 主線程繼續執行
for i in range(5):
time.sleep(1)
print(f"主線程: {i}")
# 等待線程1完成
thread1.join()
print("全部完成!")
讓我們來解析這個魔法咒語:
- 我們導入
threading
和time
模塊。 - 我們定義一個函數
print_numbers()
,該函數將由我們的線程執行。 - 我們創建一個新的線程對象,指定它應運行的函數。
- 我們使用
start()
方法啟動線程。 - 主線程繼續執行其自己的循環。
- 我們使用
join()
來等待我們的線程完成後再結束程序。
當你運行這個程序時,你會看到來自兩個線程的數字相互交錯,展示了並發執行!
線程同步
現在,想象一下我們的廚師助手試圖同時使用同一把刀——混亂對吧?這就是線程同步的用武之地。我們使用鎖定來確保一次只有一個線程可以訪問共享資源。
以下是示例:
import threading
import time
# 共享資源
counter = 0
lock = threading.Lock()
def increment_counter():
global counter
for _ in range(100000):
lock.acquire()
counter += 1
lock.release()
# 創建兩個線程
thread1 = threading.Thread(target=increment_counter)
thread2 = threading.Thread(target=increment_counter)
# 啟動線程
thread1.start()
thread2.start()
# 等待兩個線程完成
thread1.join()
thread2.join()
print(f"最終計數器值: {counter}")
在這個示例中,我們使用一個鎖來確保一次只有一個線程可以增加計數器的值,防止競態條件。
多線程優先隊列
最後但同樣重要的是,讓我們看一下多線程的一個實際應用——優先隊列。想象一下醫院急診室,病人根據病情的嚴重性而不是只是到達時間來治療。
import threading
import queue
import time
import random
# 創建一個優先隊列
task_queue = queue.PriorityQueue()
def worker():
while True:
priority, task = task_queue.get()
print(f"處理任務: {task} (優先級: {priority})")
time.sleep(random.uniform(0.1, 0.5)) # 模擬工作
task_queue.task_done()
# 創建並啟動工作線程
for _ in range(3):
thread = threading.Thread(target=worker, daemon=True)
thread.start()
# 將任務添加到隊列中
for i in range(10):
priority = random.randint(1, 5)
task = f"任務 {i}"
task_queue.put((priority, task))
# 等待所有任務完成
task_queue.join()
print("所有任務完成!")
這個示例演示了多個線程如何有效地合作處理優先隊列中的任務。
結論
恭喜你,年輕的 Python 魔法師們!你們剛剛走出了多線程魔法領域的第一步。請記住,能力越大,責任越大——明智地使用線程,它們將使你的程序更快、更有效率。
以下是我們今天涵蓋的主要線程方法的快速參考表:
方法 | 描述 |
---|---|
Thread(target=function) |
創建一個新的線程來運行指定的函數 |
start() |
開始線程的活動 |
join() |
等待線程完成 |
Lock() |
創建線程同步的鎖 |
acquire() |
獲取鎖 |
release() |
釋放鎖 |
繼續練習,保持好奇心,你將能夠像真正的 Python 大師一樣指揮線程!祝編程愉快!
Credits: Image by storyset