1

Siehe Codebeispiel unten. Das Symptom ist, dass die requests.get(url) innerhalb einer multiprocessing scheint irgendwie durch eine matplotlibfigure() blockiert werden.Requests.get im Multiprocessing-Pool durch eine Matplotlib-Zahl blockiert?

Die Zutaten dieses eher unerwartetes Verhalten zu reproduzieren, erforderlich sind:

  1. die multiprocessingPool Verwenden Sie eine Funktion auf eine Liste anzuwenden; Eine Ebene request.get(url) nach plt.figure() läuft fließend.
  2. Die Funktion für die map enthält requests.get; Andere "einfachere" Funktionen wie die Identitätsfunktion (z. B. f im Codebeispiel) können problemlos ausgeführt werden.
  3. Bevor Sie den Pool starten, erstellen Sie eine Matplotlib figure; ohne diese figure läuft der Code fließend.

Code-Beispiel:

# 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]) 

Ausgabe des Codebeispiel:

1 [<Response [200]>] 
2 ['http://stackoverflow.com'] 
3 
+0

Es funktionierte hier mit Python 2.7.9, Matplotlib 1.4.2 und Anfragen 2.4.3. –

+0

@ J.P.Petersen Ich versuchte Ihre Versionen mit 'conda env'; funktioniert immer noch nicht ... – FJDU

+0

1. Wenn dies ein neues Projekt ist, wird Python 3.6 über Python 2.7 empfohlen; 2. zum Ausführen von gleichzeitigen HTTP-Anfragen wird "Threading" gegenüber "Multiprocessing" bevorzugt; 3. Verwende 'concurrent.futures.ThreadPoolExecutor' (eingebaut in python3 oder' pip install futures' in Python 2) für [leichtere Parallelität] (http://pythonhosted.org/futures/#threadpoolexecutor-example) in Python. – Udi

Antwort

0

Wenn Sie dies in Windows ausgeführt wird, müssen Sie unter def f() in ein den gesamten Code verschieben:

if __name__ == "__main__": 

Block.

+0

Ich benutze macOS 10.12.3 – FJDU

+0

Ich habe das gleiche Problem auf macOS 10.12.3, Python 3.5.1. Es funktioniert gut auf Ubuntu 16.04 –

+0

Sie müssen wahrscheinlich einen Bug auf Matplotlib Bug Tracker öffnen – Udi

Verwandte Themen