以下是对 Python threading
模块的讲解,内容基于之前的回答,结构清晰,适合中午学习场景。讲解将简洁明了,涵盖核心概念、代码示例和注意事项,适合快速理解和应用。
Python threading 模块讲解
1. 什么是 threading
模块?
threading
是 Python 标准库的一部分,用于实现多线程编程。- 允许多个线程在同一进程中并发执行,共享内存,适合 I/O 密集型任务(如文件读写、网络请求)。
- 不适合 CPU 密集型任务,因为 Python 的 Global Interpreter Lock (GIL) 限制了线程并行执行字节码。
2. 核心功能
- 创建线程:通过
threading.Thread
类创建线程,运行指定函数。 - 线程同步:使用锁(如
Lock
、RLock
)防止数据竞争。 - 线程池:通过
concurrent.futures.ThreadPoolExecutor
管理多个线程。 - 高级工具:如
Semaphore
(限制并发访问)、Timer
(延迟执行)、Barrier
(同步多线程)。
3. 基本示例
以下是一个简单的多线程程序,计算一个数的平方和立方:
import threading
def print_square(num):
print(f"平方: {num * num}")
def print_cube(num):
print(f"立方: {num * num * num}")
# 创建线程
t1 = threading.Thread(target=print_square, args=(10,))
t2 = threading.Thread(target=print_cube, args=(10,))
# 启动线程
t1.start()
t2.start()
# 等待线程完成
t1.join()
t2.join()
# 输出示例:
# 平方: 100
# 立方: 1000
说明:
start()
启动线程,执行目标函数。join()
确保主线程等待子线程完成。- 线程并发运行,输出顺序可能因调度而异。
4. 线程同步:避免竞争条件
多个线程访问共享资源可能导致数据错误,使用锁来解决。例如:
import threading
class FakeDatabase:
def __init__(self):
self.value = 0
self._lock = threading.Lock()
def update(self, name):
print(f"线程 {name} 开始更新")
with self._lock:
local_copy = self.value
local_copy += 1
self.value = local_copy
print(f"线程 {name} 完成更新")
db = FakeDatabase()
threads = [threading.Thread(target=db.update, args=(i,)) for i in range(2)]
for t in threads:
t.start()
for t in threads:
t.join()
# 输出示例:
# 线程 0 开始更新
# 线程 0 完成更新
# 线程 1 开始更新
# 线程 1 完成更新
# 最终值: 2
说明:
Lock
确保一次只有一个线程修改value
,避免竞争条件。- 没有锁的情况下,
value
可能因交错执行而错误。
5. 线程池:高效管理多线程
使用 concurrent.futures.ThreadPoolExecutor
简化线程管理:
import concurrent.futures
def worker(task_id):
print(f"任务 {task_id} 正在运行")
return f"任务 {task_id} 完成"
with concurrent.futures.ThreadPoolExecutor(max_workers=2) as executor:
results = [executor.submit(worker, i) for i in range(3)]
# 输出示例:
# 任务 0 正在运行
# 任务 1 正在运行
# 任务 2 正在运行
说明:
ThreadPoolExecutor
限制最大并发线程数(这里为 2)。- 适合批量任务,如网络请求或文件处理。
6. 注意事项
- GIL 限制:由于 GIL,线程无法充分利用多核 CPU,适合 I/O 密集型任务。对于 CPU 密集型任务,推荐
multiprocessing
模块。 - 死锁风险:使用锁时注意避免死锁(如线程互相等待)。
- 守护线程:设置
daemon=True
使线程随主程序退出,适合后台任务。 - Python 3.13+ 无 GIL:实验性无 GIL 构建可能改善线程性能,但仍需显式同步。
7. 实际应用场景
- 网络爬虫:并发下载网页,缩短等待时间。
- 文件处理:同时读写多个文件,提高效率。
- 实时日志:后台线程记录日志,不阻塞主程序。
8. 总结
threading
模块适合 I/O 密集型任务,提供灵活的线程创建、同步和池化工具。理解 GIL 和同步机制是使用它的关键。对于更复杂的需求,可结合 queue
或 concurrent.futures
,或考虑 multiprocessing
。
推荐资源
- 官方文档:threading 模块
- 教程:Real Python 线程介绍
- 进阶:GeeksforGeeks 多线程