在初始Popen解决之前,使用Popen()启动太多进程有多大的危险?
我正在对一个充满PDF的目录进行一些处理。我迭代每个文件并使用外部调用做两件事。
首先,我从基于Xpdf的pdftohtml工具获得html表示(pdfminer太慢了)。这使输出仅为第一页:
html = check_output(['pdftohtml.exe','-f','1','-l','1','-stdout','-noframes',pdf])然后,如果满足了我的条件(我确定这是正确的文档),我将调用表格提取器来提取一个表。与检查文档相比,这是一个缓慢/长时间运行的过程,并且只发生在大约1/20个文件上。
如果我只做call(['jruby', 'C:\\jruby-1.7.4\\bin\\tabula', .....]),我将花很长时间等待提取完成,而我可以检查更多的文件(我有4核,16‘t的ram和Tabula似乎不是多线程的)。
因此,我使用Popen()来避免阻塞。
Popen(['jruby', 'C:\\jruby-1.7.4\\bin\\tabula', '-o', csv, '-f', 'CSV', '-a', "'",topBorder, ',', leftBorder, ',', bottomBorder, ',', rightBorder, "'", '-p', '1', pdf])
#where CSV is the name of the output file and pdf is the name of the input我不关心返回值(tabula正在创建一个csv文件,所以我总是可以看到它是否创建成功)。这样做意味着我可以继续在后台检查文件,并根据需要启动更多的表格处理程序(同样,只有大约20%)。
这是可行的,但它会被积压,最终会同时运行大量的tabula进程。所以我的问题是:这很糟糕吗?它使计算机在其他任何事情上都慢下来,但只要它不崩溃,并且工作得越快越好,我真的不介意(所有的4个核心始终处于100%的状态,但是内存的使用不会超过5.5GB,所以它看起来是CPU绑定的)。
如果它是坏的,有什么正确的方法来改善它?是否有一种方便的方法可以说,排队处理表格进程,这样每个核心总是有1-2个运行,但我不尝试一次处理30个文件?
发布于 2013-09-20 21:46:52
是否有一种方便的方法可以说,排队处理表格进程,这样每个核心总是有1-2个运行,但我不尝试一次处理30个文件?
是的,multiprocessing模块就是这样做的。
import multiprocessing
import subprocess
def process_pdf(path):
subprocess.call(['jruby', 'C:\\jruby-1.7.4\\bin\\tabula', path, ...])
pool = multiprocessing.Pool(3) # 3 processes
results = []
for path in search_for_files():
results.append(pool.apply_async(process_pdf, [path]))
for result in results:
result.wait()https://stackoverflow.com/questions/18926224
复制相似问题