Sorry, die Beispiele unterscheiden sich so stark, dass zumindest ich nicht erfassen kann, wieso man das hier so und dort anders macht.
Mir ist konkret unklar, wann die Worker-Funktionen zurück kehren, ob oder wann sie blockieren und wie ich prüfen kann ob alle Tasks erledigt sind, bevor mein Hauptprogramm weiter arbeitet. `submit()` wird z.B. so beschrieben, dass es die Funktion nicht sofort ausführt, sondern "scheduled", also in eine Art Warteschlange einreiht. Das ThreadPoolExecutor-Objekt scheint die Funktion dann vermutlich im nächsten freien Thread auszuführen.
Ich habe immer noch nicht verstanden, wie ich mit `shutdown()` eingreifen und alles stoppen kann. Nach meinem Verständnis geht das nicht in Verbindung mit `with`, weil `submit()` erst dann aufgerufen werden kann, wenn alle Tasks abgearbeitet sind, d.h. ich müsste ohne `with` arbeiten und in einem Loop auf ein Stopp-Signal warten o.ä. Oder am Ende des Codes einfach `shutdown(True)` aufrufen, um alle eingereihten Aufgaben noch abzuarbeiten aber keine neuen Aufgaben mehr anzunehmen... dafür fehlt mir noch der Zusammenhang. Threading & Co. sind halt kein Pappenstiel...
Wieso Queues: weil ich dachte dass Listen nicht threadsafe sind. Oder kümmert sich der abstrakte Executor selbstständig um die nötigen Locks? Außerdem stelle ich mir das so vor, dass mehrere Prozesse hintereinander arbeiten. Wenn Prozess 1 die ersten Ergebnisse liefert, greift Prozess 2 darauf zu und verarbeitet diese weiter. Noch während Prozess 2 abarbeitet, füllt Prozess 1 die Aufgaben weiter auf.
So langsam kommt Licht ins Dunkel
Durch Ausprobieren kann man Einiges herauskriegen... Hier meine Erkenntnisse:
1. So blockiert der Code nicht:
Code: Alles auswählen
import time
import concurrent.futures
# list of tasks: lower-case alphabet letters
tasks = []
for i in range(26):
tasks.append(chr(97+i))
results = []
# what to be done: transform to upper-case
def work(task):
time.sleep(0.1)
results.append(task.upper())
executor = concurrent.futures.ThreadPoolExecutor(max_workers=4)
for task in tasks:
future = executor.submit(work, task)
""" It is not blocking here, are the pending tasks processed anyway? """
print "results 1:", results
""" result 1 is incomplete... if we wait a moment, it will be completed """
time.sleep(5)
print "results 2", results
2. So blockiert der Code vor der letzten Zeile mit der `print` Ausgabe:
Code: Alles auswählen
import time
import concurrent.futures
# list of tasks: lower-case alphabet letters
tasks = []
for i in range(26):
tasks.append(chr(97+i))
results = []
# what to be done: transform to upper-case
def work(task):
time.sleep(0.1)
results.append(task.upper())
with concurrent.futures.ThreadPoolExecutor(max_workers=4) as executor:
for task in tasks:
future = executor.submit(work, task)
""" It is blocking here, so the result is already complete when printed. """
print "results:", results