Python threading 模块


以下是对 Python threading 模块的讲解,内容基于之前的回答,结构清晰,适合中午学习场景。讲解将简洁明了,涵盖核心概念、代码示例和注意事项,适合快速理解和应用。


Python threading 模块讲解

1. 什么是 threading 模块?

  • threading 是 Python 标准库的一部分,用于实现多线程编程。
  • 允许多个线程在同一进程中并发执行,共享内存,适合 I/O 密集型任务(如文件读写、网络请求)。
  • 不适合 CPU 密集型任务,因为 Python 的 Global Interpreter Lock (GIL) 限制了线程并行执行字节码。

2. 核心功能

  • 创建线程:通过 threading.Thread 类创建线程,运行指定函数。
  • 线程同步:使用锁(如 LockRLock)防止数据竞争。
  • 线程池:通过 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 和同步机制是使用它的关键。对于更复杂的需求,可结合 queueconcurrent.futures,或考虑 multiprocessing

推荐资源


发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注