Многопоточный загрузчик тормозит без причины - PullRequest
0 голосов
/ 14 июля 2020

Я работал над многопоточным парсером изображений в Python, используя requests и multiprocessing.dummy.

Скрипт работает нормально, пока не достигнет определенной точки. Тогда весь рабочий процесс становится очень медленным. Также кажется, что чем больше потоков я буду использовать, тем раньше я это испытал.

Часть загрузки выглядит так:

def download(URL):
    try:
        URL = URL.rstrip()    
        down = requests.get(URL, headers={'x-test2': 'true'})
        # Download Images 

    except BaseException as e:
        print("Error")

Часть потока выглядит так:

if __name__ == '__main__':
    ThreadPool(20).map(download, URLlist)   

Итак, мой вопрос заключается в том, что замедляет весь мой процесс загрузки, так как URL-адреса в порядке, и он должен продолжаться так же, как и раньше. Есть ли какая-то команда, которую мне не хватает, или это что-то с моей потоковой частью? (потоки закрываются неправильно ...)

Также важно, что эта проблема не появляется с меньшим списком URL-адресов.

(Но это не должно быть проблемой ограничения количества запросов со страницей, с которой я загружаю, потому что тем временем скрипт работает, и после того, как я закончил 0 проблем с точки зрения скорости и доступности страницы) Почему?

1 Ответ

1 голос
/ 14 июля 2020

Если операции с пулом замедляются с течением времени, частое закрытие пула может (а может и не помочь) помочь. Попробуйте что-нибудь простое, вроде этого ...

if __name__ == '__main__':
    max_size = # use some large value here
    for i in range(0, len(URLlist), max_size):
        st = time.time()
        pool = ThreadPool(20)    
        pool.map(download, URLlist[i: i + max_size])
        pool.close()    # should not be needed in practice
        pool.join()
        et = time.time()
        print('Processing took %.3f seconds' % (et-st))

Попробуйте другие, но большие значения max_size. Это числовые элементы из списка URL-адресов, которые ваш код будет обрабатывать перед закрытием пула и открытием другого.

Как я сказал в своем комментарии, я знаю об этой проблеме для multiprocessing.Pool (), но Я не уверен, что у ThreadPool () такая же проблема. Для mp.Pool () это происходит только с очень большими списками элементов для обработки. Когда это происходит, вы обычно видите, что использование памяти постоянно увеличивается по мере выполнения программы (так что ищите это). Я считаю, что основная проблема заключается в том, что рабочие пула создаются снова и снова, но неправильно собирают мусор, пока вы не закроете пул.

Еще одна вещь, которую следует учитывать ... время для обработки, и после того, как ваш код поработает какое-то время, многие из ваших потоков могут зависнуть из-за более медленных URL-адресов, из-за чего кажется, что работа замедляется в целом. В таком случае закрытие пула иногда не поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...