См. Пример кода ниже. Симптомом является то, что requests.get(url)
в пределах multiprocessing
Pool
, по-видимому, каким-то образом блокируется matplotlib
figure()
.Requests.get в многопроцессорном пуле, заблокированном фигурой Matplotlib?
Ингредиенты, необходимые для воспроизведения этого довольно неожиданное поведение являются:
- Используйте
multiprocessing
Pool
применить функцию к списку; равнинаrequest.get(url)
послеplt.figure()
бежит свободно. - Функция для
Pool
map
содержитrequests.get
; используя другую «более простую» функцию, такую как функция идентификации (например,f
в образце кода), бегает свободно. - Перед запуском бассейна создайте matplotlib
figure
; без этогоfigure
, код бежит свободно. Пример
Код:
# matplotlib.__version__: 1.4.3
# requests.__version__: 2.9.1
# Python version:
# 2.7.12 |Anaconda 2.3.0 (x86_64)| (default, Jul 2 2016, 17:43:17)
# [GCC 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.11.00)]
# uname -a:
# Darwin myMBP 16.4.0 Darwin Kernel Version 16.4.0:
# Thu Dec 22 22:53:21 PST 2016;
# root:xnu-3789.41.3~3/RELEASE_X86_64 x86_64 i386 MacBookPro11,3 Darwin
from matplotlib import pyplot as plt
from multiprocessing import Pool
import requests
urls = ['http://stackoverflow.com']
# Runs as expected:
p = Pool(processes=1)
print 1, p.map(requests.get, urls)
# Runs as expected:
def f(x):
return x
fig = plt.figure()
p = Pool(processes=1)
print 2, p.map(f, urls)
# Will not run (the p.map takes forever to run):
fig = plt.figure()
p = Pool(processes=1)
print 3, p.map(requests.get, urls)
# REPLACING the previous block with the following
# will again runs as expected:
fig = plt.figure()
print 4, requests.get(urls[0])
Выход образца кода:
1 [<Response [200]>]
2 ['http://stackoverflow.com']
3
Он работал здесь с Python 2.7.9, matplotlib 1.4.2 и запросами 2.4.3. –
@ J.P.Petersen Я пробовал ваши версии с 'conda env'; все еще не работает ... – FJDU
1. Если это новый проект, рекомендуется использовать python 3.6 для python 2.7; 2. для запуска одновременных HTTP-запросов, 'threading' является предпочтительным для' multiprocessing'; 3. Используйте 'concurrent.futures.ThreadPoolExecutor' (встроенный в python3 или' pip install futures' в python 2) для [упрощенного параллелизма] (http://pythonhosted.org/futures/#threadpoolexecutor-example) в python. – Udi