多进程绘图中time.strftime()生成重复文件名的问题求解
解决并行脚本生成文件时的重名覆盖问题
问题背景
并行运行脚本生成绘图时,多个进程同时生成的时间戳完全相同,导致后续进程的文件覆盖前序进程的文件。需要生成绝对唯一的文件名,同时希望能通过主进程传递变量给子脚本。
解决方案
方案1:主进程生成唯一标识符并传递给子脚本
主进程为每个任务生成唯一ID(基础时间+任务序号),通过命令行参数传递给子脚本,从根源避免文件名重复。
修改后的script0.py:
import multiprocessing as mp import os import time def execute(task_info): script_path, unique_id = task_info os.system(f"python {script_path} {unique_id}") if __name__ == "__main__": proc_num = 4 tasks = [] base_time = time.strftime("%Hh%Mm%Ss") for idx in range(proc_num): # 生成唯一ID:基础时间+任务序号 unique_id = f"{base_time}_task{idx}" tasks.append(("script1.py", unique_id)) process_pool = mp.Pool(processes=proc_num) process_pool.map(execute, tasks)
修改后的script1.py:
import sys import numpy as np import matplotlib.pyplot as plt import os dir_name = "stackoverflow_question" # 接收主进程传递的唯一ID unique_id = sys.argv[1] plot_name = f"Plot_{unique_id}" if not os.path.exists(dir_name): os.mkdir(dir_name) N = 50 x = np.random.rand(N) y = np.random.rand(N) colors = np.random.rand(N) area = (30 * np.random.rand(N))**2 plt.scatter(x, y, s=area, c=colors, alpha=0.5) plt.savefig(f"{dir_name}/{plot_name}.png", dpi=300) plt.close() # 关闭画布避免内存泄漏
方案2:子脚本结合进程ID+毫秒级时间戳生成唯一文件名
无需主进程传参,子脚本自行获取进程ID(PID),搭配精确到毫秒的时间戳,确保文件名唯一。
修改后的script1.py:
import time import os import numpy as np import matplotlib.pyplot as plt dir_name = "stackoverflow_question" # 时间戳精确到毫秒,加上当前进程ID plot_name = time.strftime("Plot_%Hh%Mm%S.%fs") + f"_pid{os.getpid()}" if not os.path.exists(dir_name): os.mkdir(dir_name) N = 50 x = np.random.rand(N) y = np.random.rand(N) colors = np.random.rand(N) area = (30 * np.random.rand(N))**2 plt.scatter(x, y, s=area, c=colors, alpha=0.5) plt.savefig(f"{dir_name}/{plot_name}.png", dpi=300) plt.close()
方案3:使用UUID生成全局唯一标识符
UUID是全局唯一的字符串,完全不会出现重复,适合需要生成大量文件的场景。
修改后的script1.py:
import uuid import numpy as np import matplotlib.pyplot as plt import os dir_name = "stackoverflow_question" # 生成UUID作为文件名核心标识 unique_uuid = uuid.uuid4().hex plot_name = f"Plot_{unique_uuid}" if not os.path.exists(dir_name): os.mkdir(dir_name) N = 50 x = np.random.rand(N) y = np.random.rand(N) colors = np.random.rand(N) area = (30 * np.random.rand(N))**2 plt.scatter(x, y, s=area, c=colors, alpha=0.5) plt.savefig(f"{dir_name}/{plot_name}.png", dpi=300) plt.close()
注意事项
- 建议给文件名加上明确后缀(如
.png),方便识别文件类型。 - 生成大量文件时,定期清理或归档旧文件,避免目录文件过多影响操作效率。
- 多进程场景下务必调用
plt.close()关闭画布,防止内存泄漏。
内容的提问来源于stack exchange,提问作者thehungrycolonel
相关产品推荐
相关产品推荐

