【发布时间】:2017-03-16 12:29:31
【问题描述】:
我想从 Python 为大约 8000 个文件启动一个外部命令。每个文件都独立于其他文件进行处理。唯一的限制是在处理完所有文件后继续执行。我有 4 个物理核心,每个都有 2 个逻辑核心(multiprocessing.cpu_count() 返回 8)。我的想法是使用一个由四个并行独立进程组成的池,这些进程将在 8 个内核中的 4 个上运行。这样我的机器应该可以同时使用。
这是我一直在做的事情:
import multiprocessing
import subprocess
import os
from multiprocessing.pool import ThreadPool
def process_files(input_dir, output_dir, option):
pool = ThreadPool(multiprocessing.cpu_count()/2)
for filename in os.listdir(input_dir): # about 8000 files
f_in = os.path.join(input_dir, filename)
f_out = os.path.join(output_dir, filename)
cmd = ['molconvert', option, f_in, '-o', f_out]
pool.apply_async(subprocess.Popen, (cmd,))
pool.close()
pool.join()
def main():
process_files('dir1', 'dir2', 'mol:H')
do_some_stuff('dir2')
process_files('dir2', 'dir3', 'mol:a')
do_more_stuff('dir3')
对一批 100 个文件进行顺序处理需要 120 秒。上面概述的多处理版本(函数process_files)批处理只需要 20 秒。但是,当我对整组 8000 个文件运行 process_files 时,我的电脑会挂起并且一小时后没有解冻。
我的问题是:
1) 我认为ThreadPool 应该初始化一个进程池(确切地说,这里是multiprocessing.cpu_count()/2 进程)。但是,我的计算机挂断了 8000 个文件而不是 100 个文件,这表明可能没有考虑到池的大小。要么,要么我做错了什么。你能解释一下吗?
2) 当每个独立进程都必须启动外部命令时,这是在 Python 下启动独立进程的正确方法,并且所有资源都不会被处理占用吗?
【问题讨论】:
-
我比较了@larsks(
ThreadPool与apply_async和子进程calls)和@Roland Smith(使用Popen对象的手动池管理)提出的解决方案。我的基准测试表明ThreadPool解决方案在实践中更快。非常感谢你们!
标签: python subprocess multiprocessing threadpool