Python高级应用系列(八):并发编程——Threading、Multiprocessing与并发模式

张开发
2026/4/19 0:08:14 15 分钟阅读

分享文章

Python高级应用系列(八):并发编程——Threading、Multiprocessing与并发模式
标签:Python | 并发 | Threading | Multiprocessing | 进程池 | GIL字数:约 4500 字建议阅读时间:13 分钟前言Python 的并发编程是一个"坑"与"利器"并存的领域。一方面,GIL(全局解释器锁)让多线程无法真正并行执行 Python 字节码;另一方面,合理选择 Threading、Multiprocessing 或 asyncio,能让程序在 I/O 密集和 CPU 密集场景下都发挥出最佳性能。本文系统讲解 Python 的三大并发方案:Threading(线程)、Multiprocessing(进程)、Concurrent.futures(高层 API),以及它们各自的适用场景和常见模式。一、Python 并发全景图Python 并发体系 ├── 线程(Threading) → 共享内存,适合 I/O 密集 ├── 进程(Multiprocessing)→ 独立内存,适合 CPU 密集 ├── 异步(asyncio) → 单线程事件循环,适合高并发 I/O └── 协程(greenlet/gevent)→ 用户态调度,适合 I/O 密集选择原则:I/O 密集(网络请求、文件读写、数据库查询)→ asyncio 或 ThreadingCPU 密集(计算、加密、压缩、图像处理)→ Multiprocessing混合型(I/O + 少量计算)→ asyncio + run_in_executor二、Threading 模块2.1 线程基础:创建与启动import threading import time def download(url: str): print(f"[{threading.current_thread().name}] 开始下载: {url}") time.sleep(1) # 模拟网络 I/O print(f"[{threading.current_thread().name}] 完成: {url}") urls = ["a.com", "b.com", "c.com", "d.com"] start = time.time() # 方式一:手动创建线程 threads = [] for url in urls: t = threading.Thread(target=download, args=(url,), name=f"Thread-{url}") t.start() threads.append(t) # 等待所有线程完成 for t in threads: t.join() print(f"总耗时: {time.time() - start:.2f}s") # ~1秒(并发)2.2 继承 Thread 类class Worker(threading.Thread): def __init__(self, task_id: int): super().__init__() self.task_id = task_id def run(self): # 线程入口必须是 run print(f"处理任务 {self.task_id}") time.sleep(0.5) print(f"任务 {self.task_id} 完成") for i in range(5): Worker(i).start()三、线程同步原语3.1 Lock:互斥锁import threading counter = 0 lock = threading.Lock() def increment(): global counter for _ in range(100000): with lock: # with lock 自动获取和释放 counter += 1 threads = [threading.Thread(target=increment) for _ in range(4)] for t in threads: t.start() for t in threads: t.join() print(counter) # 400000(正确);不用锁则小于 400000(竞争条件)3.2 RLock:可重入锁同一个线程可以多次获取同一把锁:lock = threading.RLock() def outer(): with lock: print("外层") inner() def inner(): with lock: # 同一线程再次获取 RLock ✅ 不会死锁 print("内层") outer() /

更多文章