【问题标题】:Python - Unzip .gz files in parallelPython - 并行解压缩 .gz 文件
【发布时间】:2016-03-02 08:05:37
【问题描述】:

我有多个 .gz 文件,总大小为 1TB。 如何利用 Python 2.7 并行解压缩这些文件? 循环播放文件需要太多时间。

我也试过这段代码:

filenames = [gz for gz in glob.glob(filesFolder + '*.gz')]

def uncompress(path):
    with gzip.open(path, 'rb') as src, open(path.rstrip('.gz'), 'wb') as dest:
        shutil.copyfileobj(src, dest)

with multiprocessing.Pool() as pool:
    for _ in pool.imap_unordered(uncompress, filenames, chunksize=1):
        pass

但是我收到以下错误:

  with multiprocessing.Pool() as pool:

AttributeError: __exit__

谢谢!

【问题讨论】:

  • 要使用with构造,内部使用的对象必须有__enter____exit__方法。该错误表明Pool 类没有这些,因此您不能在with 语句中使用它。
  • 我认为不是完全重复,但也许this 答案可以提供帮助?
  • 旁注:你确定CPU是瓶颈吗?您可能会遇到后端存储(磁盘?)可以处理的 IO 限制。我的猜测是并行运行多个解压缩任务会使情况变得更糟(想想寻道时间)。
  • 跟进 IO 瓶颈的想法 - 可能在解压缩之前将文件复制到 RAMdisk 中?

标签: python python-2.7 gzip


【解决方案1】:

要使用with 构造,内部使用的对象必须具有__enter____exit__ 方法。该错误表明Pool 类(或实例)没有这些,因此您不能在with 语句中使用它。 试试这个(刚刚删除了 with 语句):

import glob, multiprocessing, shutil

filenames = [gz for gz in glob.glob('.' + '*.gz')]

def uncompress(path):
    with gzip.open(path, 'rb') as src, open(path.rstrip('.gz'), 'wb') as dest:
        shutil.copyfileobj(src, dest)


for _ in multiprocessing.Pool().imap_unordered(uncompress, filenames, chunksize=1):
    pass

编辑

我同意@dhke,除非所有(或大部分)gz 文件在物理上相邻,否则与执行这些操作文件相比,对不同位置的频繁磁盘读取(在使用多处理时更频繁地调用)会更慢一个一个(串行)的文件。

【讨论】: