concurrent.futures — Starten paralleler Aufgaben¶
Hinzugefügt in Version 3.2.
Quellcode: Lib/concurrent/futures/thread.py, Lib/concurrent/futures/process.py, und Lib/concurrent/futures/interpreter.py
Das Modul concurrent.futures bietet eine High-Level-Schnittstelle für die asynchrone Ausführung von aufrufbaren Objekten.
Die asynchrone Ausführung kann mit Threads unter Verwendung von ThreadPoolExecutor oder InterpreterPoolExecutor oder separaten Prozessen unter Verwendung von ProcessPoolExecutor erfolgen. Jede implementiert dieselbe Schnittstelle, die durch die abstrakte Klasse Executor definiert ist.
Verfügbarkeit: nicht WASI.
Dieses Modul funktioniert nicht oder ist nicht auf WebAssembly verfügbar. Weitere Informationen finden Sie unter WebAssembly-Plattformen.
Executor-Objekte¶
- class concurrent.futures.Executor¶
Eine abstrakte Klasse, die Methoden zur asynchronen Ausführung von Aufrufen bereitstellt. Sie sollte nicht direkt verwendet werden, sondern über ihre konkreten Unterklassen.
- submit(fn, /, *args, **kwargs)¶
Plant das aufrufbare Objekt, fn, zur Ausführung als
fn(*args, **kwargs)und gibt einFuture-Objekt zurück, das die Ausführung des aufrufbaren Objekts repräsentiert.with ThreadPoolExecutor(max_workers=1) as executor: future = executor.submit(pow, 323, 1235) print(future.result())
- map(fn, *iterables, timeout=None, chunksize=1, buffersize=None)¶
Ähnlich wie
map(fn, *iterables), außer dassDie iterables werden sofort gesammelt und nicht verzögert, es sei denn, es wird eine buffersize angegeben, um die Anzahl der übermittelten Aufgaben zu begrenzen, deren Ergebnisse noch nicht ausgegeben wurden. Wenn der Puffer voll ist, pausiert die Iteration über die iterables, bis ein Ergebnis aus dem Puffer ausgegeben wird.
fn wird asynchron ausgeführt und mehrere Aufrufe von fn können gleichzeitig erfolgen.
Der zurückgegebene Iterator löst einen
TimeoutErroraus, wenn__next__()aufgerufen wird und das Ergebnis nicht nach timeout Sekunden ab dem ursprünglichen Aufruf vonExecutor.map()verfügbar ist. timeout kann eine Ganzzahl oder eine Gleitkommazahl sein. Wenn timeout nicht angegeben ist oderNoneist, gibt es keine Wartezeitbegrenzung.Wenn ein fn-Aufruf eine Ausnahme auslöst, wird diese Ausnahme ausgelöst, wenn ihr Wert aus dem Iterator abgerufen wird.
Bei Verwendung von
ProcessPoolExecutorzerlegt diese Methode iterables in eine Reihe von Blöcken, die sie als separate Aufgaben an den Pool übermittelt. Die (ungefähre) Größe dieser Blöcke kann durch Setzen von chunksize auf eine positive Ganzzahl angegeben werden. Für sehr lange Iterables kann die Verwendung eines großen Wertes für chunksize die Leistung im Vergleich zur Standardgröße von 1 erheblich verbessern. BeiThreadPoolExecutorundInterpreterPoolExecutorhat chunksize keine Auswirkung.Geändert in Version 3.5: Parameter chunksize hinzugefügt.
Geändert in Version 3.14: Parameter buffersize hinzugefügt.
- shutdown(wait=True, *, cancel_futures=False)¶
Signalisiert dem Executor, dass er alle verwendeten Ressourcen freigeben soll, sobald die aktuell anstehenden Futures ausgeführt sind. Aufrufe von
Executor.submit()undExecutor.map()nach dem Shutdown lösen eineRuntimeErroraus.Wenn wait
Trueist, gibt diese Methode erst zurück, wenn alle ausstehenden Futures ausgeführt sind und die dem Executor zugeordneten Ressourcen freigegeben wurden. Wenn waitFalseist, gibt diese Methode sofort zurück und die dem Executor zugeordneten Ressourcen werden freigegeben, sobald alle ausstehenden Futures ausgeführt sind. Unabhängig vom Wert von wait wird das gesamte Python-Programm erst beendet, wenn alle ausstehenden Futures ausgeführt sind.Wenn cancel_futures
Trueist, bricht diese Methode alle ausstehenden Futures ab, die der Executor noch nicht gestartet hat. Bereits abgeschlossene oder laufende Futures werden unabhängig vom Wert von cancel_futures nicht abgebrochen.Wenn sowohl cancel_futures als auch wait
Truesind, werden alle Futures, die der Executor gestartet hat, vor der Rückgabe dieser Methode abgeschlossen. Die restlichen Futures werden abgebrochen.Sie können die explizite Verwendung dieser Methode vermeiden, indem Sie den Executor als Context Manager über die
with-Anweisung verwenden, die denExecutorherunterfährt (wobei gewartet wird, als wäreExecutor.shutdown()mit wait aufTruegesetzt aufgerufen worden).import shutil with ThreadPoolExecutor(max_workers=4) as e: e.submit(shutil.copy, 'src1.txt', 'dest1.txt') e.submit(shutil.copy, 'src2.txt', 'dest2.txt') e.submit(shutil.copy, 'src3.txt', 'dest3.txt') e.submit(shutil.copy, 'src4.txt', 'dest4.txt')
Geändert in Version 3.9: Parameter cancel_futures hinzugefügt.
ThreadPoolExecutor¶
ThreadPoolExecutor ist eine Unterklasse von Executor, die einen Pool von Threads zur asynchronen Ausführung von Aufrufen verwendet.
Deadlocks können auftreten, wenn der einer Future zugeordnete aufrufbare Aufruf auf die Ergebnisse einer anderen Future wartet. Zum Beispiel
import time
def wait_on_b():
time.sleep(5)
print(b.result()) # b will never complete because it is waiting on a.
return 5
def wait_on_a():
time.sleep(5)
print(a.result()) # a will never complete because it is waiting on b.
return 6
executor = ThreadPoolExecutor(max_workers=2)
a = executor.submit(wait_on_b)
b = executor.submit(wait_on_a)
Und
def wait_on_future():
f = executor.submit(pow, 5, 2)
# This will never complete because there is only one worker thread and
# it is executing this function.
print(f.result())
executor = ThreadPoolExecutor(max_workers=1)
executor.submit(wait_on_future)
- class concurrent.futures.ThreadPoolExecutor(max_workers=None, thread_name_prefix='', initializer=None, initargs=())¶
Eine Unterklasse von
Executor, die einen Pool von höchstens max_workers Threads zur asynchronen Ausführung von Aufrufen verwendet.Alle an
ThreadPoolExecutorübermittelten Threads werden zusammengeführt, bevor der Interpreter beendet werden kann. Beachten Sie, dass der Behandlungsmechanismus, der dies tut, vor allen mitatexithinzugefügten Behandlungsmechanismen ausgeführt wird. Das bedeutet, dass Ausnahmen im Hauptthread abgefangen und behandelt werden müssen, um die Threads ordnungsgemäß zu beenden. Aus diesem Grund wird empfohlen,ThreadPoolExecutornicht für lang andauernde Aufgaben zu verwenden.initializer ist ein optionales aufrufbares Objekt, das beim Start jedes Worker-Threads aufgerufen wird; initargs ist ein Tupel von Argumenten, die an den Initialisierer übergeben werden. Sollte der initializer eine Ausnahme auslösen, werden alle aktuell anstehenden Jobs eine
BrokenThreadPool-Ausnahme auslösen, ebenso jeder Versuch, weitere Jobs an den Pool zu übermitteln.Geändert in Version 3.5: Wenn max_workers
Noneist oder nicht angegeben wird, wird es standardmäßig auf die Anzahl der Prozessoren der Maschine multipliziert mit5gesetzt, vorausgesetzt, dassThreadPoolExecutoroft zur Überlappung von E/A-Operationen anstelle von CPU-Arbeit verwendet wird und die Anzahl der Worker höher sein sollte als die Anzahl der Worker fürProcessPoolExecutor.Geändert in Version 3.6: Parameter thread_name_prefix hinzugefügt, um es Benutzern zu ermöglichen, die Namen der
threading.Threadfür von dem Pool erstellte Worker-Threads zur einfacheren Fehlerbehebung zu steuern.Geändert in Version 3.7: Argumente initializer und initargs hinzugefügt.
Geändert in Version 3.8: Der Standardwert für max_workers wird auf
min(32, os.cpu_count() + 4)geändert. Dieser Standardwert behält mindestens 5 Worker für E/A-gebundene Aufgaben bei. Er nutzt maximal 32 CPU-Kerne für CPU-gebundene Aufgaben, die den GIL freigeben. Und er vermeidet implizit die Verwendung sehr großer Ressourcen auf Maschinen mit vielen Kernen.ThreadPoolExecutor wiederverwendet jetzt auch ruhende Worker-Threads, bevor max_workers Worker-Threads gestartet werden.
Geändert in Version 3.13: Der Standardwert für max_workers wird auf
min(32, (os.process_cpu_count() or 1) + 4)geändert.
Beispiel für ThreadPoolExecutor¶
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://nonexistent-subdomain.python.org/']
# Retrieve a single page and report the URL and contents
def load_url(url, timeout):
with urllib.request.urlopen(url, timeout=timeout) as conn:
return conn.read()
# We can use a with statement to ensure threads are cleaned up promptly
with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
# Start the load operations and mark each future with its URL
future_to_url = {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]
try:
data = future.result()
except Exception as exc:
print('%r generated an exception: %s' % (url, exc))
else:
print('%r page is %d bytes' % (url, len(data)))
InterpreterPoolExecutor¶
Die Klasse InterpreterPoolExecutor verwendet einen Pool von Interpretern, um Aufrufe asynchron auszuführen. Sie ist eine Unterklasse von ThreadPoolExecutor, was bedeutet, dass jeder Worker in seinem eigenen Thread läuft. Der Unterschied hierbei ist, dass jeder Worker seinen eigenen Interpreter hat und jede Aufgabe mit diesem Interpreter ausführt.
Der größte Vorteil der Verwendung von Interpretern anstelle von nur Threads ist echte Multi-Core-Parallelität. Jeder Interpreter hat seine eigene Global Interpreter Lock, sodass Code, der in einem Interpreter ausgeführt wird, auf einem CPU-Kern laufen kann, während Code in einem anderen Interpreter ungehindert auf einem anderen Kern läuft.
Der Nachteil ist, dass das Schreiben von parallelem Code für die Verwendung mit mehreren Interpretern zusätzliche Anstrengungen erfordern kann. Dies liegt jedoch daran, dass Sie gezwungen sind, sorgfältig zu überlegen, wie und wann Interpreter interagieren, und explizit zu machen, welche Daten zwischen den Interpretern geteilt werden. Dies führt zu mehreren Vorteilen, die die zusätzliche Anstrengung ausgleichen, einschließlich echter Multi-Core-Parallelität. Zum Beispiel kann Code, der auf diese Weise geschrieben wurde, die Nachvollziehbarkeit von Parallelität erleichtern. Ein weiterer großer Vorteil ist, dass Sie sich nicht mit vielen der großen Probleme bei der Verwendung von Threads befassen müssen, wie z. B. Race Conditions.
Der Interpreter jedes Workers ist von allen anderen Interpretern isoliert. „Isoliert“ bedeutet, dass jeder Interpreter seinen eigenen Laufzeitstatus hat und völlig unabhängig voneinander arbeitet. Wenn Sie beispielsweise sys.stdout in einem Interpreter umleiten, wird er nicht automatisch an einen anderen Interpreter umgeleitet. Wenn Sie ein Modul in einem Interpreter importieren, wird es nicht automatisch in einem anderen importiert. Sie müssten das Modul separat in dem Interpreter importieren, in dem Sie es benötigen. Tatsächlich ist jedes Modul, das in einem Interpreter importiert wird, ein völlig separates Objekt von demselben Modul in einem anderen Interpreter, einschließlich sys, builtins und sogar __main__.
Isolation bedeutet, dass ein veränderbares Objekt oder andere Daten nicht von mehr als einem Interpreter gleichzeitig verwendet werden können. Das bedeutet effektiv, dass Interpreter solche Objekte oder Daten nicht tatsächlich teilen können. Stattdessen muss jeder Interpreter seine eigene Kopie haben, und Sie müssen alle Änderungen zwischen den Kopien manuell synchronisieren. Unveränderliche Objekte und Daten, wie die integrierten Singletons, Zeichenketten und Tupel aus unveränderlichen Objekten, haben diese Einschränkungen nicht.
Die Kommunikation und Synchronisation zwischen Interpretern erfolgt am effektivsten mit dedizierten Werkzeugen, wie sie in PEP 734 vorgeschlagen werden. Eine weniger effiziente Alternative ist die Serialisierung mit pickle und das anschließende Senden der Bytes über einen gemeinsamen socket oder eine pipe.
- class concurrent.futures.InterpreterPoolExecutor(max_workers=None, thread_name_prefix='', initializer=None, initargs=())¶
Eine Unterklasse von
ThreadPoolExecutor, die Aufrufe asynchron mit einem Pool von höchstens max_workers Threads ausführt. Jeder Thread führt Aufgaben in seinem eigenen Interpreter aus. Die Worker-Interpreter sind voneinander isoliert, was bedeutet, dass jeder seinen eigenen Laufzeitstatus hat und keine veränderbaren Objekte oder andere Daten gemeinsam nutzen kann. Jeder Interpreter hat seine eigene Global Interpreter Lock, was bedeutet, dass mit diesem Executor ausgeführter Code echte Multi-Core-Parallelität aufweist.Die optionalen Argumente initializer und initargs haben die gleiche Bedeutung wie bei
ThreadPoolExecutor: Der Initialisierer wird beim Erstellen jedes Workers ausgeführt, allerdings in diesem Fall im Interpreter des Workers. Der Executor serialisiert den initializer und initargs mithilfe vonpickle, wenn er sie an den Interpreter des Workers sendet.Hinweis
Der Executor kann nicht abgefangene Ausnahmen von initializer durch
ExecutionFailedersetzen.Andere Hinweise von der Elternklasse
ThreadPoolExecutorgelten hier.
submit() und map() funktionieren wie gewohnt, außer dass der Worker das aufrufbare Objekt und die Argumente mit pickle serialisiert, wenn er sie an seinen Interpreter sendet. Der Worker serialisiert ebenso den Rückgabewert, wenn er ihn zurücksendet.
Wenn die aktuelle Aufgabe eines Workers eine nicht abgefangene Ausnahme auslöst, versucht der Worker immer, die Ausnahme unverändert beizubehalten. Wenn dies erfolgreich ist, setzt er außerdem den __cause__ auf eine entsprechende Instanz von ExecutionFailed, die eine Zusammenfassung der ursprünglichen Ausnahme enthält. In dem seltenen Fall, dass der Worker die ursprüngliche Ausnahme nicht unverändert beibehalten kann, speichert er stattdessen direkt die entsprechende Instanz von ExecutionFailed.
ProcessPoolExecutor¶
Die Klasse ProcessPoolExecutor ist eine Unterklasse von Executor, die einen Pool von Prozessen zur asynchronen Ausführung von Aufrufen verwendet. ProcessPoolExecutor verwendet das Modul multiprocessing, wodurch die Global Interpreter Lock umgangen werden kann, was aber auch bedeutet, dass nur serialisierbare Objekte ausgeführt und zurückgegeben werden können.
Das Modul __main__ muss von Worker-Unterprozessen importierbar sein. Dies bedeutet, dass ProcessPoolExecutor im interaktiven Interpreter nicht funktioniert.
Das Aufrufen von Methoden von Executor oder Future aus einem an einen ProcessPoolExecutor übermittelten aufrufbaren Objekt führt zu einem Deadlock.
Beachten Sie, dass die Einschränkungen für Funktionen und Argumente, die serialisierbar sein müssen, gemäß multiprocessing.Process bei der Verwendung von submit() und map() auf einem ProcessPoolExecutor gelten. Eine Funktion, die in einer REPL oder als Lambda-Funktion definiert ist, sollte nicht erwartet werden, zu funktionieren.
- class concurrent.futures.ProcessPoolExecutor(max_workers=None, mp_context=None, initializer=None, initargs=(), max_tasks_per_child=None)¶
Eine Unterklasse von
Executor, die Aufrufe asynchron mit einem Pool von höchstens max_workers Prozessen ausführt. Wenn max_workersNoneist oder nicht angegeben wird, wird standardmäßigos.process_cpu_count()verwendet. Wenn max_workers kleiner oder gleich0ist, wird eineValueErrorausgelöst. Unter Windows muss max_workers kleiner oder gleich61sein. Wenn dies nicht der Fall ist, wird eineValueErrorausgelöst. Wenn max_workersNoneist, beträgt der gewählte Standardwert höchstens61, auch wenn mehr Prozessoren verfügbar sind. mp_context kann einmultiprocessing-Kontext oderNonesein. Er wird zum Starten der Worker verwendet. Wenn mp_contextNoneist oder nicht angegeben wird, wird der Standard-multiprocessing-Kontext verwendet. Siehe Kontexte und Startmethoden.initializer ist ein optionales aufrufbares Objekt, das beim Start jedes Worker-Prozesses aufgerufen wird; initargs ist ein Tupel von Argumenten, die an den Initialisierer übergeben werden. Sollte der initializer eine Ausnahme auslösen, werden alle aktuell anstehenden Jobs eine
BrokenProcessPool-Ausnahme auslösen, ebenso jeder Versuch, weitere Jobs an den Pool zu übermitteln.max_tasks_per_child ist ein optionales Argument, das die maximale Anzahl von Aufgaben angibt, die ein einzelner Prozess ausführen kann, bevor er beendet und durch einen neuen Worker-Prozess ersetzt wird. Standardmäßig ist max_tasks_per_child
None, was bedeutet, dass Worker-Prozesse so lange leben, wie der Pool. Wenn ein Maximum angegeben wird, wird standardmäßig die „spawn“-Multiprocessing-Startmethode verwendet, wenn kein mp_context-Parameter angegeben ist. Diese Funktion ist inkompatibel mit der „fork“-Startmethode.Geändert in Version 3.3: Wenn einer der Worker-Prozesse abrupt beendet wird, wird jetzt ein
BrokenProcessPool-Fehler ausgelöst. Zuvor war das Verhalten undefiniert, aber Operationen am Executor oder seinen Futures froren oft ein oder führten zu Deadlocks.Geändert in Version 3.7: Das Argument mp_context wurde hinzugefügt, um Benutzern die Steuerung der Startmethode für von dem Pool erstellte Worker-Prozesse zu ermöglichen.
Argumente initializer und initargs hinzugefügt.
Geändert in Version 3.11: Das Argument max_tasks_per_child wurde hinzugefügt, um Benutzern die Steuerung der Lebensdauer von Workern im Pool zu ermöglichen.
Geändert in Version 3.12: Auf POSIX-Systemen, wenn Ihre Anwendung mehrere Threads hat und der
multiprocessing-Kontext die Startmethode"fork"verwendet: Die intern aufgerufene Funktionos.fork()zum Starten von Workern kann eineDeprecationWarningauslösen. Übergeben Sie einen mp_context, der so konfiguriert ist, dass eine andere Startmethode verwendet wird. Weitere Erläuterungen finden Sie in der Dokumentation zuos.fork().Geändert in Version 3.13: max_workers verwendet standardmäßig
os.process_cpu_count()anstelle vonos.cpu_count().Geändert in Version 3.14: Die Standardmethode zum Starten von Prozessen (siehe Kontexte und Startmethoden) wurde von fork weg geändert. Wenn Sie die fork-Startmethode für
ProcessPoolExecutorbenötigen, müssen Sie explizitmp_context=multiprocessing.get_context("fork")übergeben.- terminate_workers()¶
Versucht, alle laufenden Worker-Prozesse sofort durch Aufrufen von
Process.terminatefür jeden einzelnen zu beenden. Intern wird auchExecutor.shutdown()aufgerufen, um sicherzustellen, dass alle anderen mit dem Executor verbundenen Ressourcen freigegeben werden.Nach dem Aufruf dieser Methode sollte der Aufrufer keine weiteren Aufgaben mehr an den Executor übermitteln.
Hinzugefügt in Version 3.14.
- kill_workers()¶
Versucht, alle laufenden Worker-Prozesse sofort durch Aufrufen von
Process.killfür jeden einzelnen zu beenden. Intern wird auchExecutor.shutdown()aufgerufen, um sicherzustellen, dass alle anderen mit dem Executor verbundenen Ressourcen freigegeben werden.Nach dem Aufruf dieser Methode sollte der Aufrufer keine weiteren Aufgaben mehr an den Executor übermitteln.
Hinzugefügt in Version 3.14.
Beispiel für ProcessPoolExecutor¶
import concurrent.futures
import math
PRIMES = [
112272535095293,
112582705942171,
112272535095293,
115280095190773,
115797848077099,
1099726899285419]
def is_prime(n):
if n < 2:
return False
if n == 2:
return True
if n % 2 == 0:
return False
sqrt_n = int(math.floor(math.sqrt(n)))
for i in range(3, sqrt_n + 1, 2):
if n % i == 0:
return False
return True
def main():
with concurrent.futures.ProcessPoolExecutor() as executor:
for number, prime in zip(PRIMES, executor.map(is_prime, PRIMES)):
print('%d is prime: %s' % (number, prime))
if __name__ == '__main__':
main()
Future-Objekte¶
Die Klasse Future kapselt die asynchrone Ausführung eines aufrufbaren Objekts. Future-Instanzen werden von Executor.submit() erstellt.
- Klasse concurrent.futures.Future¶
Kapselt die asynchrone Ausführung eines aufrufbaren Objekts.
Future-Instanzen werden vonExecutor.submit()erstellt und sollten nicht direkt erstellt werden, außer zu Testzwecken.- cancel()¶
Versucht, den Aufruf abzubrechen. Wenn der Aufruf gerade ausgeführt wird oder abgeschlossen ist und nicht abgebrochen werden kann, gibt die Methode
Falsezurück, andernfalls wird der Aufruf abgebrochen und die Methode gibtTruezurück.
- cancelled()¶
Gibt
Truezurück, wenn der Aufruf erfolgreich abgebrochen wurde.
- running()¶
Gibt
Truezurück, wenn der Aufruf gerade ausgeführt wird und nicht abgebrochen werden kann.
- done()¶
Gibt
Truezurück, wenn der Aufruf erfolgreich abgebrochen oder abgeschlossen wurde.
- result(timeout=None)¶
Gibt den vom Aufruf zurückgegebenen Wert zurück. Wenn der Aufruf noch nicht abgeschlossen ist, wartet diese Methode bis zu timeout Sekunden. Wenn der Aufruf in timeout Sekunden nicht abgeschlossen ist, wird ein
TimeoutErrorausgelöst. timeout kann eine ganze Zahl oder ein Float sein. Wenn timeout nicht angegeben ist oderNoneist, gibt es keine Wartezeitbegrenzung.Wenn das Future vor der Fertigstellung abgebrochen wird, wird
CancelledErrorausgelöst.Wenn der Aufruf eine Ausnahme ausgelöst hat, löst diese Methode dieselbe Ausnahme aus.
- exception(timeout=None)¶
Gibt die vom Aufruf ausgelöste Ausnahme zurück. Wenn der Aufruf noch nicht abgeschlossen ist, wartet diese Methode bis zu timeout Sekunden. Wenn der Aufruf in timeout Sekunden nicht abgeschlossen ist, wird ein
TimeoutErrorausgelöst. timeout kann eine ganze Zahl oder ein Float sein. Wenn timeout nicht angegeben ist oderNoneist, gibt es keine Wartezeitbegrenzung.Wenn das Future vor der Fertigstellung abgebrochen wird, wird
CancelledErrorausgelöst.Wenn der Aufruf ohne Ausnahme abgeschlossen wurde, wird
Nonezurückgegeben.
- add_done_callback(fn)¶
Hängt das aufrufbare Objekt fn an das Future an. fn wird mit dem Future als einzigem Argument aufgerufen, wenn das Future abgebrochen wird oder abgeschlossen ist.
Hinzugefügte aufrufbare Objekte werden in der Reihenfolge aufgerufen, in der sie hinzugefügt wurden, und immer in einem Thread aufgerufen, der zum Prozess gehört, der sie hinzugefügt hat. Wenn das aufrufbare Objekt eine Unterklasse von
Exceptionauslöst, wird es protokolliert und ignoriert. Wenn das aufrufbare Objekt eine Unterklasse vonBaseExceptionauslöst, ist das Verhalten undefiniert.Wenn das Future bereits abgeschlossen oder abgebrochen wurde, wird fn sofort aufgerufen.
Die folgenden
Future-Methoden sind für die Verwendung in Unit-Tests undExecutor-Implementierungen vorgesehen.- set_running_or_notify_cancel()¶
Diese Methode sollte nur von
Executor-Implementierungen vor der Ausführung der mit demFutureverbundenen Arbeit und von Unit-Tests aufgerufen werden.Wenn die Methode
Falsezurückgibt, wurde dasFutureabgebrochen, d. h.Future.cancel()wurde aufgerufen und gabTruezurück. Alle Threads, die auf die Fertigstellung desFuturewarten (d. h. überas_completed()oderwait()), werden geweckt.Wenn die Methode
Truezurückgibt, wurde dasFuturenicht abgebrochen und wurde in den laufenden Zustand versetzt, d. h. Aufrufe vonFuture.running()gebenTruezurück.Diese Methode kann nur einmal aufgerufen werden und kann nicht nach dem Aufruf von
Future.set_result()oderFuture.set_exception()aufgerufen werden.
- set_result(result)¶
Legt das Ergebnis der mit dem
Futureverbundenen Arbeit auf result fest.Diese Methode sollte nur von
Executor-Implementierungen und Unit-Tests verwendet werden.Geändert in Version 3.8: Diese Methode löst
concurrent.futures.InvalidStateErroraus, wenn dasFuturebereits abgeschlossen ist.
- set_exception(exception)¶
Legt das Ergebnis der mit dem
Futureverbundenen Arbeit auf dieExceptionexception fest.Diese Methode sollte nur von
Executor-Implementierungen und Unit-Tests verwendet werden.Geändert in Version 3.8: Diese Methode löst
concurrent.futures.InvalidStateErroraus, wenn dasFuturebereits abgeschlossen ist.
Modulfunktionen¶
- concurrent.futures.wait(fs, timeout=None, return_when=ALL_COMPLETED)¶
Wartet auf die Fertigstellung der
Future-Instanzen (möglicherweise erstellt von verschiedenenExecutor-Instanzen), die durch fs angegeben sind. Doppelte Futures in fs werden entfernt und nur einmal zurückgegeben. Gibt ein benanntes 2-Tupel von Mengen zurück. Die erste Menge, genanntdone, enthält die Futures, die vor Abschluss des Wartens abgeschlossen wurden (fertige oder abgebrochene Futures). Die zweite Menge, genanntnot_done, enthält die Futures, die nicht abgeschlossen wurden (ausstehende oder laufende Futures).timeout kann verwendet werden, um die maximale Anzahl von Sekunden zu steuern, die gewartet werden soll, bevor zurückgekehrt wird. timeout kann eine ganze Zahl oder ein Float sein. Wenn timeout nicht angegeben ist oder
Noneist, gibt es keine Wartezeitbegrenzung.return_when gibt an, wann diese Funktion zurückkehren soll. Es muss eine der folgenden Konstanten sein:
Konstante
Beschreibung
- concurrent.futures.FIRST_COMPLETED¶
Die Funktion wird zurückkehren, wenn ein Future abgeschlossen oder abgebrochen wird.
- concurrent.futures.FIRST_EXCEPTION¶
Die Funktion wird zurückkehren, wenn ein Future durch Auslösen einer Ausnahme abgeschlossen wird. Wenn kein Future eine Ausnahme auslöst, ist dies äquivalent zu
ALL_COMPLETED.- concurrent.futures.ALL_COMPLETED¶
Die Funktion wird zurückkehren, wenn alle Futures abgeschlossen oder abgebrochen werden.
- concurrent.futures.as_completed(fs, timeout=None)¶
Gibt einen Iterator über die
Future-Instanzen (möglicherweise erstellt von verschiedenenExecutor-Instanzen) zurück, die durch fs gegeben sind, und liefert Futures, sobald sie abgeschlossen sind (fertige oder abgebrochene Futures). Duplizierte Futures in fs werden einmal zurückgegeben. Futures, die vor dem Aufruf vonas_completed()abgeschlossen wurden, werden zuerst geliefert. Der zurückgegebene Iterator löst einTimeoutErroraus, wenn__next__()aufgerufen wird und das Ergebnis nach timeout Sekunden ab dem ursprünglichen Aufruf vonas_completed()nicht verfügbar ist. timeout kann eine ganze Zahl oder ein Float sein. Wenn timeout nicht angegeben ist oderNoneist, gibt es keine Wartezeitbegrenzung.
Siehe auch
- PEP 3148 – Futures - Berechnungen asynchron ausführen
Der Vorschlag, der diese Funktion für die Aufnahme in die Python-Standardbibliothek beschrieb.
Ausnahmeklassen¶
- Ausnahme concurrent.futures.CancelledError¶
Wird ausgelöst, wenn ein Future abgebrochen wird.
- Ausnahme concurrent.futures.TimeoutError¶
Ein veralteter Alias für
TimeoutError, der ausgelöst wird, wenn eine Future-Operation das angegebene Timeout überschreitet.Geändert in Version 3.11: Diese Klasse wurde zu einem Alias von
TimeoutError.
- Ausnahme concurrent.futures.BrokenExecutor¶
Diese Ausnahme, die von
RuntimeErrorabgeleitet ist, wird ausgelöst, wenn ein Executor aus irgendeinem Grund beschädigt ist und nicht zum Übermitteln oder Ausführen neuer Aufgaben verwendet werden kann.Hinzugefügt in Version 3.7.
- Ausnahme concurrent.futures.InvalidStateError¶
Wird ausgelöst, wenn eine Operation auf einem Future ausgeführt wird, die im aktuellen Zustand nicht zulässig ist.
Hinzugefügt in Version 3.8.
- Ausnahme concurrent.futures.thread.BrokenThreadPool¶
Diese Ausnahme, die von
BrokenExecutorabgeleitet ist, wird ausgelöst, wenn einer der Worker einesThreadPoolExecutorbei der Initialisierung fehlgeschlagen ist.Hinzugefügt in Version 3.7.
- Ausnahme concurrent.futures.interpreter.BrokenInterpreterPool¶
Diese Ausnahme, die von
BrokenThreadPoolabgeleitet ist, wird ausgelöst, wenn einer der Worker einesInterpreterPoolExecutorbei der Initialisierung fehlgeschlagen ist.Hinzugefügt in Version 3.14.
- Ausnahme concurrent.futures.interpreter.ExecutionFailed¶
Wird von
InterpreterPoolExecutorausgelöst, wenn der angegebene Initialisierer fehlschlägt, oder vonsubmit(), wenn eine nicht abgefangene Ausnahme aus der übermittelten Aufgabe auftritt.Hinzugefügt in Version 3.14.
- Ausnahme concurrent.futures.process.BrokenProcessPool¶
Diese Ausnahme, die von
BrokenExecutor(früherRuntimeError) abgeleitet ist, wird ausgelöst, wenn einer der Worker einesProcessPoolExecutorauf eine nicht saubere Weise beendet wurde (z. B. wenn er von außen beendet wurde).Hinzugefügt in Version 3.3.