多处理Python 3

多处理Python 3,python,multithreading,multiprocessing,pickle,python-camelot,Python,Multithreading,Multiprocessing,Pickle,Python Camelot,我一直在尝试为python 3上的一系列任务创建一个多处理池。任务如下: 1.阅读pdf文件并捕获pdf文件中的表格,然后- 2.创建pickle文件以存储表对象 3.加载pickle文件 为了进行测试,我在三个pdf文件上以串行和并行模式运行python代码。排序是在200秒内运行整个过程,并在工作目录中创建pickle文件。但是,多处理不会在目录中生成pickle文件,但运行该进程需要39秒 排序代码如下所示: os.chdir('C:/Users/dir_path') def p

我一直在尝试为python 3上的一系列任务创建一个多处理池。任务如下: 1.阅读pdf文件并捕获pdf文件中的表格,然后- 2.创建pickle文件以存储表对象 3.加载pickle文件

为了进行测试,我在三个pdf文件上以串行和并行模式运行python代码。排序是在200秒内运行整个过程,并在工作目录中创建pickle文件。但是,多处理不会在目录中生成pickle文件,但运行该进程需要39秒

排序代码如下所示:

os.chdir('C:/Users/dir_path')

    def process_table(pdf):
        for pdf in pdfs:
            tables = camelot.read_pdf(pdf, pages = 'all', flag_size=True, copy_text=['v'], line_scale=40) 
            print(f'Process {os.getpid()} Processing File Name:{pdf}\nTotal Tables found:{len(tables)}')
            with open(pdf.split('.pdf')[0] + '.pkl', 'wb') as f:
                pickle.dump(tables, f)
                print(f'Process {os.getpid()} Pickle file created for: {pdf}')
            with open(pdf.split('.pdf')[0] + '.pkl', 'rb') as g:
                pickle.load(g)
                print(f'Process {os.getpid()} Pickle file loaded: {pdf}')

    def process_handler():    
        start_time = time.time()
        pdfs = [file_name for file_name in os.listdir()]
        process_table(pdfs)
        end = time.time()
        duration = round(time.time() - start_time)
        print(f'Whole Process completed in {duration} second(s)') 


if __name__ == '__main__':
    process_handler()    
代码的输出如下所示:

os.chdir('C:/Users/dir_path')

def process_table(pdf):
        tables = camelot.read_pdf(pdf, pages = 'all', flag_size=True, copy_text=['v'], line_scale=40) 
        print(f'Process {os.getpid()} Processing File Name:{pdf}\nTotal Tables found:{len(tables)}')
        with open(pdf.split('.pdf')[0] + '.pkl', 'wb') as f:
            pickle.dump(tables, f)
            print(f'Process {os.getpid()} Pickle file created for: {pdf}')
        with open(pdf.split('.pdf')[0] + '.pkl', 'rb') as g:
            pickle.load(g)
            print(f'Process {os.getpid()} Pickle file loaded for: {pdf}')

def process_handler():    
    start_time = time.time()

    files = [file_name for file_name in os.listdir()]
    with ThreadPoolExecutor() as executor:
        executor.map(process_table, files)

    duration = round(time.time() - start_time)
    print(f'Whole Process completed in {duration} second(s)') 

if __name__ == '__main__':
    process_handler()
多处理的代码如下所示:

os.chdir('C:/Users/dir_path')

def process_table(pdf):
        tables = camelot.read_pdf(pdf, pages = 'all', flag_size=True, copy_text=['v'], line_scale=40) 
        print(f'Process {os.getpid()} Processing File Name:{pdf}\nTotal Tables found:{len(tables)}')
        with open(pdf.split('.pdf')[0] + '.pkl', 'wb') as f:
            pickle.dump(tables, f)
            print(f'Process {os.getpid()} Pickle file created for: {pdf}')
        with open(pdf.split('.pdf')[0] + '.pkl', 'rb') as g:
            pickle.load(g)
            print(f'Process {os.getpid()} Pickle file loaded for: {pdf}')

def process_handler():    
    start_time = time.time()

    files = [file_name for file_name in os.listdir()]
    with ThreadPoolExecutor() as executor:
        executor.map(process_table, files)

    duration = round(time.time() - start_time)
    print(f'Whole Process completed in {duration} second(s)') 

if __name__ == '__main__':
    process_handler()
我非常感谢您对此的宝贵反馈。这是至关重要的,因为有时候20 MB的pdf文件需要很长时间才能转换为包含存储在其中的表对象的pickle文件。因此,该进程被卡在第一个作业(即大小为20MB的pdf)上,在第一个作业完成之前无法移动到下一个作业

谢谢

几项

  • 我只使用了我发现效果相当好的多处理池
  • process\u table
    在map函数之外使用
    pdfs
    调用,串行处理也是如此
  • work\u项目
    据我所知不包含任何内容,除了没有
  • 使用列表参数(
    pdf
    )调用
    process\u table
    ,然后使用全局
    pdfs
    变量
我的建议是:

import multiprocessing as mp

files = [file_name for file_name in os.listdir()]
with mp.Pool(mp.cpu_count()-1) as pool:
    pool.map(files, process_table)

我尝试了你建议的方法,但看起来像是jupyter笔记本电脑,我不得不手动中断代码处理。相反,我尝试了下面的代码块:
files=[file\u name for file\u name in os.listdir()],其中ThreadPoolExecutor()作为executor:executor.map(process\u table,files)
代码完成这个过程需要22秒,这几乎是序列化所用时间的十分之一。但是,我没有看到在我的工作环境中创建和保存的pickle文件directory@Nipun不要忘了在
process_table
中的
pdf
上删除迭代。我不明白它为什么不写任何东西——检查你认为它正在写的路径。您是否从print语句中获得任何输出?运行代码后只有一个输出,即:“整个过程在39秒内完成”。除此之外,它不会打印其他语句,也不会在工作目录中创建pickle文件。我已经根据你的建议更新了我的代码,现在处理时间减少到39秒。我不知道为什么昨天它显示了22秒。我已经编辑了我的上述文章,并包含了更新的代码now@Nipun,您发布的代码不太管用,但使用ThreadPoolExecutor时,您必须使用iterable的结果,否则它什么也做不了;所以executor.map(process_table,pdf)中的r
:print(r)
感谢您的另一次更新!我确实试过了,但出现了鬼脚本错误。我忘记提到的一件事是,camelot依赖于ghostscript,因此在运行多处理代码时需要在后面激活ghostscript.exe文件。您是否认为代码对其他工具的依赖性可能是多处理代码无法工作的原因?