當你需要在 Python 中執行多個任務,但又不希望它們相互阻塞時,可以使用 threading
模組。
threading
模組允許你在單個程序中創建多個執行緒,這些執行緒可以同時運行,從而實現並行執行多個任務的效果。
同步模式:每個任務按照順序執行,後面的任務必須等待前面的任務執行完成
非同步模式:各自執行各自的任務
這裡的同步概念,並非為同步做很多事情,而是有點排隊的概念,同一個步序上。
非同步則就是不同步序,而可以同時做很多事情。
在此程式範例中,程式是由上往下開始執行,plan_A跑完才會再跑plan_B。
def plan_A():
for i in range(3):
print(f'plan_A執行: {i} 次')
time.sleep(0.5)
def plan_B():
for i in range(3):
print(f'plan_B執行: {i} 次')
time.sleep(0.5)
plan_A()
plan_B()
plan_A執行: 0 次
plan_A執行: 1 次
plan_A執行: 2 次
plan_B執行: 0 次
plan_B執行: 1 次
plan_B執行: 2 次
由輸出結果來看,同時間一起執行了plan_A與plan_B這兩個函式。
import threading
import time
def plan_A():
for i in range(3):
print(f'plan_A執行: {i} 次')
time.sleep(0.5)
def plan_B():
for i in range(3):
print(f'plan_B執行: {i} 次')
time.sleep(0.5)
# 建立新的執行緒
plan_A_thread = threading.Thread(target = plan_A)
plan_B_thread = threading.Thread(target = plan_B)
# 執行執行緒
plan_A_thread.start()
plan_B_thread.start()
plan_A執行: 0 次
plan_B執行: 0 次
plan_A執行: 1 次
plan_B執行: 1 次
plan_B執行: 2 次
plan_A執行: 2 次
創建執行緒: 使用 Thread
類可以創建一個新的執行緒。你可以將要執行的函式或方法傳遞給 Thread
類的構造函數。例如:
import threading
def my_function():
# 執行你的任務
pass
thread = threading.Thread(target=my_function)
啟動執行緒:
使用 start()
方法來啟動一個執行緒。一旦執行緒啟動,它將執行其目標函式。
thread.start()
等待執行緒結束:
使用 join()
方法來等待執行緒結束。這將使程序阻塞,直到線程完成其任務並結束。
thread.join()
加入了join()
等待執行緒,
import threading
import time
def plan_A():
for i in range(3):
print(f'plan_A執行: {i} 次')
time.sleep(0.5)
def plan_B():
for i in range(3):
print(f'plan_B執行: {i} 次')
time.sleep(0.5)
# 建立新的執行緒
plan_A_thread = threading.Thread(target = plan_A)
plan_B_thread = threading.Thread(target = plan_B)
# 執行plan_A執行緒
plan_A_thread.start()
# join()等待執行緒,直到該執行緒完成才會進行後續動作。
plan_A_thread.join()
# 執行plan_B執行緒
plan_B_thread.start()
plan_A執行: 0 次
plan_A執行: 1 次
plan_A執行: 2 次
plan_B執行: 0 次
plan_B執行: 1 次
plan_B執行: 2 次
多個執行緒共用同一個 Lock,一開始只會先執行第一個被鎖住的執行緒,等解鎖後才會執行後續的執行緒。
依這範例來解說Lock的用法,當plan_A執行時,迴圈跑到第三圈時就解開鎖,plan_B就會開始跑
import threading
import time
def plan_A():
lock.acquire()
for i in range(5):
print(f'plan_A執行: {i} 次')
time.sleep(0.5)
if i == 2:
lock.release()
def plan_B():
lock.acquire()
for i in range(5):
print(f'plan_B執行: {i} 次')
time.sleep(0.5)
lock.release()
# 建立 Lock
lock =threading.Lock()
# 建立新的執行緒
plan_A_thread = threading.Thread(target = plan_A)
plan_B_thread = threading.Thread(target = plan_B)
# 執行plan_A執行緒
plan_A_thread.start()
# 執行plan_B執行緒
plan_B_thread.start()
plan_A執行: 0 次
plan_A執行: 1 次
plan_A執行: 2 次
plan_A執行: 3 次
plan_B執行: 0 次
plan_A執行: 4 次
plan_B執行: 1 次
plan_B執行: 2 次
plan_B執行: 3 次
plan_B執行: 4 次