Futures in Python 3.2

Gunnar Beutner —  19.04.2012 — Leave a comment

Seit Version 3.2 unterstützt Python sogenannte “Futures”: Futures sind Tasks, die asynchron ausgeführt werden. Sobald der Benutzer auf den Rückgabewert eines Futures zugreift, wartet die aufrufende Funktion, bis der Task abgeschlossen ist und der Rückgabewert zur Verfügung steht.

Folgendes Beispiel (aus der Python-Dokumentation) zeigt, wie Futures verwendet werden können:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import concurrent.futures
import urllib.request
 
URLS = ['http://www.foxnews.com/',
        'http://www.cnn.com/',
        'http://europe.wsj.com/',
        'http://www.bbc.co.uk/',
        'http://some-made-up-domain.com/']
 
def load_url(url, timeout):
    return urllib.request.urlopen(url, timeout=timeout).read()
 
with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
    future_to_url = dict((executor.submit(load_url, url, 60), url)
                         for url in URLS)
 
    for future in concurrent.futures.as_completed(future_to_url):
        url = future_to_url[future]
        if future.exception() is not None:
            print('%r generated an exception: %s' % (url,
                                                     future.exception()))
        else:
            print('%r page is %d bytes' % (url, len(future.result())))

Das Script erstellt zunächst ein ThreadPoolExecutor-Objekt. Dieses stellt einen Thread-Pool dar, in dem die anschließend erstellten Tasks ausgeführt werden. Optional kann hier die maximale Anzahl an Threads (max_workers) angegeben werden. Wer rechenintensive Tasks verwendet, sollte lieber die ProcessPoolExecutor-Klasse verwenden, da Python-Code in mehreren Threads aufgrund des “Global Interpreter Lock” nicht parallel abläuft.

Mit der “submit”-Methode des ThreadPoolExecutors werden die Tasks dem Thread-Pool zugewiesen und dort eigenständig im Hintergrund ausgeführt.

Die “as_completed”-Methode liefert anschließend alle Tasks in der Reihenfolge zurück, in der sie abgeschlossen wurden. Über die “result”-Methode eines einzelnen Tasks kann auf den Rückgabewert des Tasks zugegriffen werden.

Weitere Informationen zu Futures in Python gibt es z.B. in der Python-Dokumentation. Das Future/Promise-Konzept wird auch von einer Reihe anderer Sprachen unterstützt, so z.B. in C++11 mit std::future.

39.thumbnail Futures in Python 3.2

Autor: Gunnar Beutner

Vor seinem Eintritt bei NETWAYS arbeitete Gunnar bei einem großen deutschen Hostingprovider, wo er bereits viel Erfahrung in der Softwareentwicklung für das Servermanagement sammeln konnte. Bei uns kümmert er sich vor allem um verschiedene Kundenprojekte, aber auch eigene Tools wie inGraph oder in Zukunft um Icinga2.