request.get зависает при вызове в multiprocessing.Pool

У меня есть следующий код:

def process_url(url):
    print '111'
    r = requests.get(url)
    print '222' # <-- never even gets here
    return


urls_to_download = [list_or_urls]
PARALLEL_WORKERS = 4

pool = Pool(PARALLEL_WORKERS)
pool.map_async(process_url, urls_to_download)
pool.close()
pool.join()

Каждый раз, когда я это делаю, он запускает первые четыре элемента, а затем просто зависает. Я не думаю, что это проблема тайм-аута, так как загрузка четырех URL-адресов происходит очень быстро. Только после получения этих первых четырех он зависает на неопределенный срок.

Что мне нужно сделать, чтобы исправить это?


person David542    schedule 20.09.2014    source источник
comment
Что произойдет, если вы просто вызовете функцию process_url() из одного процесса/скрипта или из интерактивной оболочки Python? Кажется довольно очевидным, что проблема лежит где-то внутри request.get() и, вероятно, блокирует какое-то соединение или операцию ввода (чтение/выборка). Что произойдет, если вы используете известный доступный URL? Например, google.com/?#q=current+time.   -  person Jim Dennis    schedule 20.09.2014
comment
Да, он работает в одном потоке.   -  person David542    schedule 20.09.2014
comment
Попробуйте добавить явный возврат. Также я бы лично рекомендовал не использовать печать или другой консольный ввод-вывод из дочерних процессов. Лучшая модель программирования состоит в том, чтобы родительский процесс был диспетчером и консольным контроллером ввода-вывода, а дочерние/рабочие процессы возвращали свои результаты через потоки (или, возможно, заставляя их всех записывать в какую-либо БД или другое согласованное хранилище данных).   -  person Jim Dennis    schedule 20.09.2014
comment
Добавление явного возврата, похоже, здесь не помогло.   -  person David542    schedule 20.09.2014
comment
Я не вижу ничего особенно плохого в коде, который будет работать так, как вы описываете, кроме отсутствия мьютекса вокруг отпечатков. Какая платформа? Окна? * Никс?   -  person Michael Petch    schedule 20.09.2014
comment
Вы говорите многопоточность, это библиотека многопроцессорности? Если это так, попробуйте изменить map_async на просто карту. Если вы используете map_async, вам нужно получить возвращаемый объект результата и либо подождать, либо получить для него результаты. Поскольку вы не ждете, вы закрываете пул до того, как он успел сделать свою работу.   -  person tdelaney    schedule 20.09.2014
comment
@tdelaney Задачи по-прежнему будут выполняться до завершения, даже если close/join вызываются сразу после map_async. close просто означает, что больше нельзя отправлять задачи, а join означает «Подождите, пока все ожидающие задачи не будут выполнены».   -  person dano    schedule 20.09.2014
comment
@ user1436531 Кажется, я не могу воспроизвести это в Windows или Linux. Это происходит с любым набором URL-адресов, которые вы ему даете?   -  person dano    schedule 20.09.2014
comment
@ David542 Эта проблема решена? Я столкнулся с той же проблемой.   -  person user2552108    schedule 28.02.2018
comment
Это старая проблема, но она может быть полезна для будущих читателей. Я столкнулся с той же проблемой при использовании PyCharm на Mac с Anaconda python 3.7. Если нажать «Отладка» для выполнения, он застрянет на request.geturl(), но если нажать «Выполнить», он запустится без каких-либо проблем. В PyCharm есть ошибка.   -  person smm    schedule 29.01.2021