如何使用多线程在python中解压缩多个gz文件?

Sat*_*esh 7 python linux multithreading gzip

我有多个gz文件,总大小约为120GB.我想将这些文件解压缩(gzip)到同一目录并删除现有的gz文件.目前我们正在手动执行此操作,并且需要更多时间来解压缩使用gzip -d <filename>.
有没有办法可以通过创建python脚本或任何其他技术并行解压缩这些文件.目前这些文件位于Linux机器上.

And*_*ini 8

您可以使用多处理池轻松完成此操作:

import gzip
import multiprocessing
import shutil

filenames = [
    'a.gz',
    'b.gz',
    'c.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
Run Code Online (Sandbox Code Playgroud)

此代码将生成一些进程,每个进程将一次提取一个文件.

在这里我选择了chunksize=1,以避免一些文件大于平均值时停止进程.


sel*_*bie 2

解压缩文件所花费的大部分时间gunzipgzip -d来自 I/O 操作(读取和写入磁盘)。它甚至可能比实际解压缩数据所花费的时间还要多。您可以通过在后台运行多个 gzip 作业来利用这一点。由于某些作业在 I/O 上被阻塞,因此另一个作业实际上可以运行,而无需在队列中等待。

gunzip您可以通过在后台运行多个进程来加快整个文件集的解压缩速度。每个服务提供一组特定的文件。

您可以在 BASH 中快速完成一些简单的事情。将文件列表拆分为单独的命令,并使用 将其&作为后台作业启动。然后wait每一项工作都完成。

我建议您同时进行 2 到 2*N 份工作。其中 N 是计算机上的核心或逻辑处理器的数量。适当进行实验以获得正确的数字。

您可以在 BASH 中轻松创建一些东西。

#!/bin/bash

argarray=( "$@" )
len=${#argarray[@]}

#declare 4 empty array sets
set1=()
set2=()
set3=()
set4=()

# enumerate over each argument passed to the script
# and round robin add it to one of the above arrays

i=0
while [ $i -lt $len ]
do

    if [ $i -lt $len ]; then
        set1+=( "${argarray[$i]}" )
        ((i++))
    fi

    if [ $i -lt $len ]; then
        set2+=( "${argarray[$i]}" )
        ((i++))
    fi

    if [ $i -lt $len ]; then
        set3+=( "${argarray[$i]}" )
        ((i++))
    fi

    if [ $i -lt $len ]; then
        set4+=( "${argarray[$i]}" )
        ((i++))
    fi
done

# for each array, start a background job
gzip -d ${set1[@]} &
gzip -d ${set2[@]} &
gzip -d ${set3[@]} &
gzip -d ${set4[@]} &

# wait for all jobs to finish    
wait
Run Code Online (Sandbox Code Playgroud)

在上面的示例中,我为每个作业选择了 4 个文件并启动了两个单独的作业。您可以轻松扩展脚本以拥有更多作业、每个进程更多文件,并将文件名作为命令行参数。