在Python中,線程(Thread)是一種輕量級的執行單元,可以并發執行多個線程,每個線程獨立執行任務。線程是作業系統中排程和執行任務的基本機關,它可以與其他線程共享程序的資源和記憶體空間。
Python線程基本實作
Python提供了内置的`threading`子產品,用于建立和管理線程。使用`threading`子產品可以建立新的線程對象,并通過調用線程對象的`start()`方法來啟動線程的執行。線程對象可以執行任意的可調用對象(如函數、方法等)作為線程的任務,通過定義這些任務可以實作并發執行的功能。
下面是一個簡單的線程示例:
import threading
import time
def print_numbers():
for i in range(5):
print(f"Thread 1: {i}")
time.sleep(1)
def print_letters():
for letter in "ABCDE":
print(f"Thread 2: {letter}")
time.sleep(1)
# 建立線程對象
thread1 = threading.Thread(target=print_numbers)
thread2 = threading.Thread(target=print_letters)
# 啟動線程
thread1.start()
thread2.start()
# 等待線程執行完畢
thread1.join()
thread2.join()
print("Main thread exiting.")
在上述示例中,我們定義了兩個函數`print_numbers()`和`print_letters()`,分别用于列印數字和字母。然後,我們建立了兩個線程對象`thread1`和`thread2`,并分别指定線程的任務函數。接着,通過調用`start()`方法來啟動線程的執行。最後,使用`join()`方法等待線程執行完畢,確定主線程在所有線程完成後退出。
運作以上代碼,你将看到類似以下的輸出:
Thread 1: 0
Thread 2: A
Thread 1: 1
Thread 2: B
Thread 1: 2
Thread 2: C
Thread 1: 3
Thread 2: D
Thread 1: 4
Thread 2: E
Main thread exiting.
可以看到,兩個線程交替執行,每個線程執行一次任務後暫停一秒,然後切換到另一個線程執行。這樣就實作了簡單的并發執行。
需要注意的是,線程之間的切換是由作業系統的線程排程器控制的,是以線程的執行順序可能會有不确定性。是以,在使用線程時,需要考慮線程間的同步和互斥,以避免并發通路共享資源導緻的問題。
Python線程同步方式
在Python中,為了保證多線程環境下的線程安全性,可以使用各種同步機制和工具來實作線程間的同步和互斥。下面是幾種常見的Python線程安全同步的方式的示例:
1. 互斥鎖(Lock):
```python
import threading
# 建立互斥鎖對象
import threading
# 建立互斥鎖對象
lock = threading.Lock()
shared_resource = 0
def increment():
global shared_resource
for _ in range(100000):
# 擷取互斥鎖
lock.acquire()
shared_resource += 1
# 釋放互斥鎖
lock.release()
# 建立多個線程來調用increment函數
threads = []
for _ in range(5):
t = threading.Thread(target=increment)
threads.append(t)
t.start()
# 等待所有線程執行完畢
for t in threads:
t.join()
print("Result:", shared_resource)
上述示例中,使用`threading.Lock()`建立了一個互斥鎖對象`lock`。在`increment()`函數中,通過調用`lock.acquire()`擷取互斥鎖,執行臨界區代碼,然後使用`lock.release()`釋放互斥鎖。這樣可以確定每次隻有一個線程可以通路臨界區,進而保證線程安全。
2. 信号量(Semaphore):
import threading
# 建立信号量對象
semaphore = threading.Semaphore(2)
def task():
# 請求信号量
semaphore.acquire()
try:
# 臨界區代碼
print("Executing task")
finally:
# 釋放信号量
semaphore.release()
# 建立多個線程來調用task函數
threads = []
for _ in range(5):
t = threading.Thread(target=task)
threads.append(t)
t.start()
# 等待所有線程執行完畢
for t in threads:
t.join()
在上述示例中,使用`threading.Semaphore(2)`建立了一個信号量對象`semaphore`,并設定初始值為2。在`task()`函數中,通過調用`semaphore.acquire()`請求信号量,執行臨界區代碼,然後使用`semaphore.release()`釋放信号量。信号量的初始值為2,是以最多允許兩個線程同時進入臨界區,其他線程需要等待。
3. 條件變量(Condition):
import threading
# 建立條件變量對象
condition = threading.Condition()
queue = []
def producer():
with condition:
# 生産者線程等待條件滿足
while len(queue) >= 5:
condition.wait()
# 生産者線程向隊列中添加元素
item = "Item"
queue.append(item)
print("Produced:", item)
# 通知消費者線程
condition.notify()
def consumer():
with condition:
# 消費者線程等待條件滿足
while len(queue) == 0:
condition.wait()
# 消費者線程從隊列中取出元素
總結
線程是一種用于并發執行任務的執行單元,Python的`threading`子產品提供了建立和管理線程的功能。通過建立線程對象,并指定線程的任務函數,可以實作多個線程的并發執行。但需要注意線程間的同步和互斥,以確定線程安全。