2013-12-09 87 views
0

所以我有两个python脚本。第一个是扫描数千个文件的解析器,第二个是一个调度器,用于扫描数百个独立的目录。我的问题是这样的:Python:多进程池中的强制num进程

我有有限的磁盘资源量,每次扫描使用大约1GB的本地sqlite3存储。我需要限制进程的数量,以便在进程的最大数量运行时,我不会得到磁盘IO错误,这是我一直在得到的。

我试过使用下面的代码来分叉扫描并保持进程为8,但是当我在我的临时目录(其中存储临时本地文件的地方)中显示的实际上有超过8个文件显示我的我没有正确地限制进程(我使用os.remove在扫描完成后摆脱临时文件)。

这是我的,仅仅fork了关闭的过程与井格式化命令

def execute_scan(cmd): 
    try: 
     log("Executing "+ str(cmd)) 
     subprocess.call(cmd, shell=False) 
    except Exception as e: 
     log(e) 
     log(cmd) 

这是在我的主要方法,其中getCommand(OBJ)中的对象的数据转换到命令阵列执行扫描方法。

tasks = [getCommand(obj) for obj in scanQueue if getCommand(obj) is not None] 
multiprocessing.Pool(NUM_PROCS).map(execute_scan, tasks) 

我可以用任何意见,我可以得到,因为我处理大量的数据和我的硬盘并不大。

非常感谢!

+1

我会再次重复一遍:[并行化I/O绑定任务会导致比在单个线程(或进程)中运行任务更糟的运行时间](http://stackoverflow.com/a/20421535/1595865) 。使用多线程或进程只有在处理CPU绑定任务时才有用(并且不是每次都是这样) – goncalopp

+0

您没有显示删除临时文件的任何代码,但这可能是问题所在。查看临时文件以间接推断有多少进程正在运行是奇怪的;-)使用OS工具直接计算进程的数量。 'Pool(NUM_PROCS)'创建*完全*'NUM_PROCS'进程 - 不多也不少。 –

+0

@TimPeters正如我在描述中提到的那样,我使用os.remove(path)去除临时文件,并且该部分工作正常。 – onetwopunch

回答

0

即使我可能已经使用多关于这个应用程序使用一个简短的教程,事实证明,因为IO到sqlite3的数据库是瓶颈,多实际上是减缓下来就像goncalopp预测的一样。

0

gevent.pool.Pool可能是适合您的解决方案。因为gevent使用greenlet来执行并发操作,并且一次只能运行一个greenlet。

在你的情况下,首先将池的大小设置为一个合适的数字,这意味着最多只有一些greenlet可以做一些I/O操作。然后将执行扫描任务的功能转换为greenlet并将其添加到池中,以便由集线器 greenlet调度。

以下是有关的gevent.pool.Pool