multiprocessing模块

Python的GIL限制了多进程并发,使用 multiprocessing 模块 开启多进程并行处理任务,让 Python 真正用上多核 CPU,速度暴涨!

多进程的优势在哪?

  • CPU 全核利用multiprocessing 可以用满你的 4核/8核 CPU;
  • pool.map() 轻松调度任务;

场景:对一个大文件夹的所有.txt文件进行批量处理

比如,你要统计每个文本文件中的关键词数量,或进行格式转换、数据提取。

 1 import os
 2 import time
 3 from multiprocessing import Pool, cpu_count
 4 
 5 script_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
 6 
 7 # 要处理的文件夹路径
 8 FOLDER_PATH = script_dir + "/txtfile"
 9 
10 # 定义你的文本处理逻辑
11 def process_file(file_path):
12     with open(file_path, "r", encoding="utf-8") as f:
13         content = f.read()
14     word_count = len(content.split())
15     print(f"{os.path.basename(file_path)} 有 {word_count} 个单词")
16     return word_count
17 
18 # 获取所有 txt 文件路径
19 def get_txt_files(folder):
20     return [os.path.join(folder, f) for f in os.listdir(folder) if f.endswith(".txt")]
21 
22 def main():
23     start = time.time()
24     files = get_txt_files(FOLDER_PATH)
25 
26     # 创建进程池,核心数 = CPU 核心数
27     with Pool(processes=cpu_count()) as pool:
28         pool.map(process_file, files)
29 
30     print(f"所有文件处理完成,用时 {time.time() - start:.2f} 秒")
31 
32 if __name__ == "__main__":
33     main()
执行结果:

file1.txt 有 72 个单词
file2.txt 有 64 个单词
file3.txt 有 62 个单词
file4.txt 有 91 个单词
所有文件处理完成,用时 6.74 秒

那么有人要问,多进程总行了吧?多进程确实能绕过 GIL 的限制,利用多核 CPU,但多进程也有它的问题:

  • 资源消耗大: 每个进程都有自己独立的内存空间,进程多了,内存消耗蹭蹭往上涨。
  • 进程间通信复杂: 进程间数据共享和通信,比线程要麻烦不少。
  • 上下文切换开销: 进程切换的开销,比线程切换更大。

所以,多进程也不是万能的,尤其是在 I/O 密集型 的任务面前,比如网络请求、文件读写等等,多进程的优势就没那么明显了。

这个时候可以考虑异步编程,使用asynico模块,是Python标准库,用于编写I/O操作代码。下面改用异步编程实现方法如下:

 1 import os
 2 import time
 3 import asyncio
 4 import aiofiles
 5 
 6 script_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
 7 
 8 # 要处理的文件夹路径
 9 FOLDER_PATH = script_dir + "/txtfile"
10 
11 # 异步处理单个文件
12 async def process_file(file_path):
13     async with aiofiles.open(file_path, "r", encoding="utf-8") as f:
14         content = await f.read()
15     word_count = len(content.split())
16     print(f"{os.path.basename(file_path)} 有 {word_count} 个单词")
17     return word_count
18 
19 # 获取所有 txt 文件路径
20 def get_txt_files(folder):
21     return [os.path.join(folder, f) for f in os.listdir(folder) if f.endswith(".txt")]
22 
23 async def main():
24     start = time.time()
25     files = get_txt_files(FOLDER_PATH)
26 
27     # 并发执行所有文件处理任务
28     tasks = [process_file(file) for file in files]
29     await asyncio.gather(*tasks)
30 
31     print(f"所有文件处理完成,用时 {time.time() - start:.2f} 秒")
32 
33 if __name__ == "__main__":
34     asyncio.run(main())

运行结果:

file1.txt 有 72 个单词
file2.txt 有 64 个单词
file3.txt 有 62 个单词
file4.txt 有 91 个单词
所有文件处理完成,用时 0.01 秒

在I/O密集任务处理时,对比多进程,可见使用异步实现,耗时最短,性能有很大提升。

 应用场景扩展:

  • 批量爬虫:抓取网页/下载图片
  • 多文件转换:如批量 PDF 转 TXT
  • 数据处理:并行处理 CSV/日志文件
  • CPU 密集型任务:图像识别、加密计算
posted on 2025-08-14 13:27  Jasongo  阅读(22)  评论(0)    收藏  举报