2023-09-11 22:17:28
Python的多线程编程主要通过内置的threading模块实现,适用于I/O密集型任务,但受限于GIL(全局解释器锁),对计算密集型任务效果有限。以下是threading模块的详细解析及实践指南:
一、基础线程创建与管理创建线程通过threading.Thread类实例化线程对象,指定目标函数(target)和参数(args):
import threadingdef task(name): print(f"线程 {name}: 开始执行") # 模拟I/O操作 print(f"线程 {name}: 执行完毕")thread1 = threading.Thread(target=task, args=("T1",))thread2 = threading.Thread(target=task, args=("T2",))启动与等待线程
start():启动线程,线程函数开始执行。
join():阻塞主线程,直到子线程完成。
thread1.start()thread2.start()thread1.join()thread2.join()print("所有线程完成")锁(Lock)防止竞态条件,确保共享资源的原子操作:
counter = 0lock = threading.Lock()def increment(): global counter for _ in range(100000): with lock: # 自动获取和释放锁 counter += 1threads = [threading.Thread(target=increment) for _ in range(5)]for t in threads: t.start()for t in threads: t.join()print(f"最终计数: {counter}") # 输出500000其他同步原语
RLock:可重入锁,同一线程可多次获取。
Semaphore:限制同时访问资源的线程数。
Condition:线程间基于条件通信。
Event:通过标志位控制线程等待/唤醒。
queue.Queue提供线程安全的队列,适合生产者-消费者模型:
import queuedef producer(q): for i in range(5): q.put(f"数据-{i}") print(f"生产: 数据-{i}")def consumer(q): while True: try: item = q.get(timeout=1) print(f"消费: {item}") q.task_done() except queue.Empty: breakq = queue.Queue()threading.Thread(target=producer, args=(q,)).start()threading.Thread(target=consumer, args=(q,)).start()五、高级工具:线程池(ThreadPoolExecutor)通过concurrent.futures.ThreadPoolExecutor简化线程管理,自动调度任务并收集结果:
from concurrent.futures import ThreadPoolExecutordef process_data(data): print(f"处理: {data}") return data.upper()with ThreadPoolExecutor(max_workers=3) as executor: futures = [executor.submit(process_data, f"item_{i}") for i in range(10)] for future in futures: print(future.result())自动管理线程生命周期。
限制并发数,避免资源耗尽。
简化结果获取(通过Future对象)。
通过合理选择并发模型和同步工具,可以高效实现Python多线程编程,平衡性能与代码复杂性。