Запуск shutil.make_archive в многопоточных файлах, случайно отсутствующих

#python #multithreading #zip

Вопрос:

Пишет сценарий, который сжимает каждый подкаталог по пути, указанному аргументом команды, и удаляет исходные подкаталоги. Для однопоточных случаев это работает нормально, но когда я запускаю его в многопоточном режиме с использованием concurrent.futures.ThreadPoolExecutor() (auto_zip()) (auto_zip_multi_thread()) некоторые файлы могут не быть включены в сжатый zip. Процент отсутствующих файлов каждый раз разный, и запуск его несколько раз в одном и том же каталоге каждый раз будет давать разные результаты. Процесс может быть завершен без каких-либо недостатков. Я не могу воспроизвести это так, но что я могу сделать, чтобы исправить это? A Я не знаю разницы, потому что аналогичный скрипт, который расстегивает молнию и удаляет исходную молнию, работает нормально.

 import shutil
from concurrent import futures
def task(paths):
    while True:
        try:
            path = next(paths)
            shutil.make_archive(path, 'zip', path)
        except StopIteration:
            break

with futures.ThreadPoolExecutor(max_workers=4) as ex:
    for i in range(4):
        ex.submit(task, paths)
 

Ответ №1:

make_archive() Не является потокобезопасным. Вместо этого она решается вызовом команды subprocess.run() внутри . cd zip

 import subprocess

def task(paths):
    while True:
        try:
            path = next(paths)
            cmd = f"zip -r {path}.zip {path}"
            subprocess.run(cmd)
        except StopIteration:
            break