Можно ли использовать многопоточность Python для чтения количества файлов из числа папок и обработки этих файлов для получения комбинированного результата? - PullRequest
0 голосов
/ 28 сентября 2018

Мне нужно проанализировать количество файлов журнала по количеству папок, и я хочу ускорить анализ этих файлов журнала.Я должен найти некоторые конкретные строки из строк всех этих файлов, чтобы получить окончательную статистику в объединенной форме.Я не уверен, как я могу добиться этого с помощью многопоточности Python и насколько это эффективно.Я прошел различные уроки, но не ясно, как будет выполняться обработка файлов в случае переменных файлов в многопоточности.Любое предложение по этому вопросу было бы здорово.Заранее большое спасибо.

1 Ответ

0 голосов
/ 28 сентября 2018

Что ж, самый простой способ научиться использовать многопоточность, я думаю, это использовать класс ThreadPoolExecutor в модуле concurrent.futures, поскольку это всего на пару строк больше, чем обычный синхронный цикл for.Особенно с Python 3, но его можно адаптировать к Python 2.7.

По сути, у вас есть пул (куча) потоков, ожидающих работы.Работа - это обычно просто метод / функция, которую вы отправляете в пул вместе с параметрами, а ThreadPool обрабатывает все остальное (назначение задач доступным ресурсам и планирование).

Допустим, моя структура каталогов журнала похожа наИтак:

~ ❯ tree log
log
├── 1.log
├── 2.log
├── 3.log
└── schedules
    ├── 1.log
    ├── 2.log
    └── 3.log

1 directory, 6 files

Итак, сначала вы получите свой список файлов (Python 3).

import glob
list_of_files = list(glob.iglob('log/**/*.log', recursive=True))

Каждый файл (просто строковая переменная прямо сейчас) - это то, к чему вы хотите потокработа над.Итак, у вас есть универсальный метод, принимающий параметр файла, чтобы найти интересную строку в каждом файле.В основном то же самое, если вы сделали обычную программу на Python для, например, так:

def find_string(file):
    # insert your specific code to find your string
    # including opening the file and such
    # returning values also possible see further down
    print(file)

Так что теперь вам просто нужно отправить эти кусочки работы в ThreadPool.

from concurrent.futures import ThreadPoolExecutor

# We can use a with statement to ensure threads are cleaned up promptly
with ThreadPoolExecutor() as executor:
    # Basically the same as if you did the normal for-loop
    for file in list_of_files:
        # But you submit your method to the Pool instead.
        future = executor.submit(find_string, file) # see future.result() too

    print("All tasks complete")

Вот хороший полный пример здесь , ищите ThreadPoolExecutor Example, который открывает список веб-сайтов и печатает размер в байтах.Что вы можете изменить в поиске файлов.

Узким местом, которое может быть здесь, является огромное количество файлов, будет скорость чтения с диска.Если бы у вас были файлы журналов на нескольких дисках, это было бы решением.

Другая рекомендация состоит в том, что многопоточность обычно используется для сетевых операций или операций ввода-вывода.Так что чтение файлов - это хорошее применение.Тем не менее, вы также делаете некоторую обработку.В зависимости от того, насколько сильно загружен процессор, вы можете посмотреть на ProcessPoolExecutor для того, что использует модуль multiprocessing.Который имеет тот же интерфейс, что и ThreadPoolExecutor.

Надеюсь, что имеет смысл.

...