Python使用多进程/多线程加速多文件加密的实现咨询
问题分析
- 你此前的多线程方案没有提速有两个原因:
- 加密属于CPU密集型任务,Python的全局解释器锁(GIL)会限制多线程在CPU密集场景下的并行能力,同一时间只能有一个线程执行Python字节码,无法利用多核CPU性能
- 你的实现仅开启了1个线程执行原有串行逻辑,本身就没有做任务拆分并行
- 多进程可以绕过GIL限制,实现真正的多核并行计算,适配你的加密场景,是可行的优化方案。
多进程实现代码
首先我们把单文件加密逻辑抽离出来,同时将密钥生成逻辑提前到主进程执行,避免每个子进程重复计算浪费资源:
import base64 import multiprocessing from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC from cryptography.hazmat.backends import default_backend from cryptography.fernet import Fernet # 单文件加密函数,接收文件路径和预生成的Fernet加密实例为参数 def encrypt_single_file(file_path, fernet_obj): try: with open(file_path, 'rb') as f: original_data = f.read() encrypted_data = fernet_obj.encrypt(original_data) with open(file_path, 'wb') as f: f.write(encrypted_data) return f"{file_path} 加密完成" except Exception as e: return f"{file_path} 加密失败:{str(e)}" if __name__ == '__main__': # 主进程预生成密钥和Fernet实例,仅计算一次 password = bytes('asd123','utf-8') salt = bytes('asd123','utf-8') kdf = PBKDF2HMAC( algorithm=hashes.SHA256(), length=32, salt=salt, iterations=10000, backend=default_backend() ) key = base64.urlsafe_b64encode(kdf.derive(password)) fernet_instance = Fernet(key) # 待加密文件列表 files = [ 'D:/folder/asd.txt', 'D:/folder/qwe.mp4', 'D:/folder/qwe.jpg' ] # 初始化进程池,默认进程数等于CPU核心数,可手动通过processes参数指定数量 with multiprocessing.Pool() as pool: # 构造任务参数列表 task_params = [(file, fernet_instance) for file in files] # 批量执行任务并获取返回结果 exec_results = pool.starmap(encrypt_single_file, task_params) # 输出所有任务执行状态 for result in exec_results: print(result)
注意事项
- 主逻辑必须放在
if __name__ == '__main__'代码块下,这是Windows系统运行多进程程序的强制要求 - 如果待加密文件体积非常大,可适当调小进程池的进程数,避免内存占用过高
- 建议加密前提前备份原文件,避免异常情况导致数据损坏
内容的提问来源于stack exchange,提问作者Sanket
相关产品推荐
相关产品推荐

