Что ж, самый простой способ научиться использовать многопоточность, я думаю, это использовать класс 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
.
Надеюсь, что имеет смысл.