1
源代码:
def main_function(file_name, workdir, data_rastervalu, outdir):
pass
方法一:
import multiprocessing
from tqdm import tqdm
pool = multiprocessing.Pool(processes=4)
processes, ans = [], []
for file_name in tqdm(files_list):
processes.append(pool.apply_async(main_function, args=(file_name, workdir, data_rastervalu, outdir)))
for process in processes:
data = process.get()
ans.append(data)
pool.close()
pool.join()
方法二:
你可以尝试使用concurrent.futures模块中的ThreadPoolExecutor来优化你的代码,它能更方便地处理并行任务并跟踪进度:
首先,确保你已经导入了concurrent.futures模块:
from concurrent.futures import ThreadPoolExecutor
然后,你可以尝试修改你的代码,如下所示:
# 创建 ThreadPoolExecutor 对象
executor = ThreadPoolExecutor(max_workers=4)
# 使用列表推导式替代循环
futures = [executor.submit(main_function, file_name, workdir, data_rastervalu, outdir) for file_name in tqdm(files_list)]
# 获取结果
ans = [future.result() for future in futures]
# 关闭 executor
executor.shutdown()
这段代码将使用线程池来执行main_function函数,并且通过executor.submit将任务提交到线程池中。executor.shutdown() 会在所有任务完成后关闭线程池。
这样,你就可以同时进行多个任务并跟踪进度了。请注意,这里的max_workers参数可以根据你的需求进行调整,以控制线程池的并发数。
2. 问题分析
在你的代码中,使用了multiprocessing.Pool来创建一个进程池,同时使用了tqdm来显示进度条。
tqdm在默认配置下,会将进度条渲染到标准输出(stdout)。然而,在多进程的环境中,由于每个子进程都有自己的stdout,因此会导致进度条信息被打印到各个子进程的stdout中,而无法在主进程中显示。
当你的代码运行时,所有的子进程会在后台并行执行计算,而主进程会立即进行下一步的代码执行,也就是说,在 for file_name in tqdm(files_list) 这行代码执行的同时,main_function会被提交给进程池并在后台执行。
因此,你会看到tqdm的进度条似乎先快速完成,然后才会开始计算。实际上,计算是在后台并行进行的,只是你看不到具体的进度。
3. 问题修改
tqdm(processes)
for file_name in tqdm(files_list):
processes.append(pool.apply_async(main_function, args=(file_name, workdir, data_rastervalu, outdir, sector_id)))
for process in tqdm(processes):
data = process.get()
ans.append(data)
pool.close()
pool.join()