不同文件的python多处理

时间:2017-02-02 01:23:55

标签: python python-2.7 multiprocessing

试图更好地理解这个: https://pymotw.com/2/multiprocessing/basics.html

我有20多个“大”日志(每个日志大约是6-9gig但是压缩,即log1 ... 20.gz)

我的python脚本将遍历指定目录中的每个日志,并计算出特定列的总数,然后写入文件并转到下一个日志文件。我注意到,当我这样做时,我没有使用系统中的所有核心。因此,为了使用更多核心,我做了这个

script1.py  < folder 1 (contains logs 1-5 , write to report1-5.txt) 
script2.py  < folder 2 (contains logs 6-10, write to report6-10.txt)
script3.py  < folder 3 (contains logs 11-15, write to report11-15.txt)
script4.py  < folder 4 (contains logs 16-20, write to report16-20.txt

理想情况下,我只需要script1.py&lt;文件夹1(包含所有20个日志并写入report.txt)

如果我启用“import multiprocessing”,我将能够实现拥有1个脚本和许多工作人员通过不同的文件,还是会有许多工作人员试图处理销售log.gz文件?或者我错过了解释信息

2 个答案:

答案 0 :(得分:4)

如果我正确理解了您的问题,那么您正在寻找一种加快gzip压缩日志文件处理速度的好方法。

您需要回答的第一个问题是当前进程是CPU绑定还是IO绑定。这意味着:当您运行script.py < folder 1时,请观看它,例如使用top,您的进程是否达到100%的CPU使用率?如果是,那么您的进程受CPU限制(即CPU是瓶颈)。如果是这种情况,那么python中的并行化将帮助您。如果不是(并且肯定不是因为光盘将成为你的瓶颈,除非gz文件位于不同的磁盘上),那么你不需要打扰,因为你不会从中获得更多的速度。

要并行化,您基本上有两个选择:

  1. python :您需要按照建议使用多处理。但要实现这一点,您不能只导入多处理,您需要明确说明每个流程需要做什么,例如:

    from multiprocessing import Pool, Queue
    
    def crunch_file(queue):
        while not queue.empty()
            filename = queue.get()
            # gunzip file, do processing, write to reportx-y.txt
    
    if __name__ == '__main__':
        queue = Queue()
        # put all filenames into queue with os.walk() and queue.put(filename)
        pool = Pool(None, crunch_file, (queue,))
        pool.close() # signal that we won't submit any more tasks to pool
        pool.join() # wait until all processes are done
    

    有几点需要注意:

    • 使用Pool(None, ...) python将计算出你拥有的核心数量,并将为每个cpu核心启动一个进程
    • 使用Queue可以帮助您永远不会有空闲进程:如果其中一个进程已经完成了他的文件,它将占用队列中的下一个
  2. bash :由于您似乎不熟悉pythons多处理,并且不同的进程不需要彼此交谈,因此更容易开始,例如并行4个python程序,例如

    script.py  < folder 1 &
    script.py  < folder 2 &
    script.py  < folder 3 &
    script.py  < folder 4 &
    

答案 1 :(得分:0)

是的你走在正确的轨道上。我总是做类似的事情。运行得更快。你需要先解压缩文件。全局拾取文件并将它们以文件名列表传递给pool.map(fn,lst)我应该添加一个SSD是我使用的,如果你使用常规HD旋转,也许没有速度改进可悲的是。 SSD虽然很棒,但却很棒。不要使用Queue,关闭,加入,这些都是不必要的,所以只需使用map()

即可