本文目录导读:

在Python中,实现线程等待主要有以下几种方法,我会通过具体案例来说明:
使用 join() 方法(最常用)
import threading
import time
def worker(name, delay):
print(f"线程 {name} 开始工作")
time.sleep(delay)
print(f"线程 {name} 工作完成")
return f"{name}的结果"
# 创建线程
threads = []
for i in range(3):
t = threading.Thread(target=worker, args=(f"Worker-{i}", i+1))
threads.append(t)
t.start()
# 等待所有线程完成
for t in threads:
t.join() # 等待线程结束
print("所有线程已完成,主线程继续执行")
使用 Event 对象(条件等待)
import threading
import time
def waiter(event, name):
print(f"线程 {name} 等待事件...")
event.wait() # 等待事件被设置
print(f"线程 {name} 收到事件信号")
time.sleep(2)
print(f"线程 {name} 继续执行")
def setter(event):
time.sleep(3)
print("设置事件信号")
event.set() # 设置事件
event = threading.Event()
# 创建等待线程
wait_threads = []
for i in range(3):
t = threading.Thread(target=waiter, args=(event, f"Waiter-{i}"))
wait_threads.append(t)
t.start()
# 创建信号发送线程
setter_thread = threading.Thread(target=setter, args=(event,))
setter_thread.start()
# 等待所有线程完成
for t in wait_threads + [setter_thread]:
t.join()
print("程序结束")
使用 Lock 实现互斥等待
import threading
import time
class Counter:
def __init__(self):
self.value = 0
self.lock = threading.Lock()
def increment(self, name):
with self.lock: # 自动获取和释放锁
print(f"线程 {name} 获取锁")
temp = self.value
time.sleep(0.1)
self.value = temp + 1
print(f"线程 {name} 释放锁,当前值: {self.value}")
counter = Counter()
threads = []
for i in range(5):
t = threading.Thread(target=counter.increment, args=(f"Thread-{i}",))
threads.append(t)
t.start()
# 等待所有线程完成
for t in threads:
t.join()
print(f"最终计数值: {counter.value}")
使用 Condition 实现更复杂的等待模式
import threading
import time
import random
class ResourcePool:
def __init__(self, size):
self.resources = [f"Resource-{i}" for i in range(size)]
self.condition = threading.Condition()
def acquire(self, name):
with self.condition:
while len(self.resources) == 0:
print(f"线程 {name} 等待资源...")
self.condition.wait() # 等待资源可用
resource = self.resources.pop()
print(f"线程 {name} 获取 {resource}")
return resource
def release(self, resource):
with self.condition:
self.resources.append(resource)
print(f"释放 {resource}")
self.condition.notify() # 通知等待的线程
pool = ResourcePool(2)
def worker(name):
resource = pool.acquire(name)
time.sleep(random.uniform(1, 3)) # 模拟使用资源
pool.release(resource)
# 创建更多线程,演示资源等待
threads = []
for i in range(5):
t = threading.Thread(target=worker, args=(f"Worker-{i}",))
threads.append(t)
t.start()
for t in threads:
t.join()
print("所有资源使用完成")
使用 Semaphore 控制并发数量
import threading
import time
import random
def limited_worker(semaphore, name):
print(f"线程 {name} 尝试获取信号量")
with semaphore:
print(f"线程 {name} 获得信号量,开始工作")
time.sleep(random.uniform(1, 3))
print(f"线程 {name} 完成工作,释放信号量")
# 最多允许3个线程同时执行
semaphore = threading.Semaphore(3)
threads = []
for i in range(10):
t = threading.Thread(target=limited_worker, args=(semaphore, f"Thread-{i}"))
threads.append(t)
t.start()
for t in threads:
t.join()
print("所有线程完成")
| 方法 | 用途 | 特点 |
|---|---|---|
join() |
等待线程结束 | 最简单,最常用 |
Event |
等待事件触发 | 适合线程间信号通知 |
Lock |
互斥访问 | 保证同一时间只有一个线程访问 |
Condition |
条件等待 | 等待特定条件满足 |
Semaphore |
限制并发数 | 控制资源访问数量 |
选择建议:
- 简单等待线程结束:使用
join() - 线程间需要信号通知:使用
Event - 需要保护共享资源:使用
Lock或RLock - 复杂的生产者-消费者模式:使用
Condition - 控制并发访问数量:使用
Semaphore
这些方法可以根据具体需求组合使用,实现更复杂的线程同步和等待逻辑。