Python Academy · Lektion

ThreadPoolExecutor

Kør opgaver samtidigt

Lektion 2 af 413 trin

ThreadPoolExecutor er en gratis Python Academy-lektion på CoddyKit. Dette er lektion 2 af 4. Du kan læse hele lektionen gratis nedenfor — og derefter øve dig praktisk i browseren med en indbygget kodeeditor og en AI-vejleder, der er tilgængelig døgnet rundt. Den er en del af læringsforløbet i Python Academy, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. Python Academy-kurset indeholder 4 lektioner i alt.

Hvorfor bruge en trådpulje?

Det er besværligt at oprette og vente på tråde manuelt. concurrent.futures.ThreadPoolExecutor administrerer en pulje af arbejdertråde for dig og returnerer resultater på en enkel måde.

from concurrent.futures import ThreadPoolExecutor

def square(n):
    return n * n

with ThreadPoolExecutor() as ex:
    future = ex.submit(square, 5)
    print(future.result())

submit og Future

submit() planlægger et kald og returnerer straks et Future. Du kalder .result() på det for at hente værdien, og kaldet blokerer, indtil værdien er klar.

from concurrent.futures import ThreadPoolExecutor

def greet(name):
    return 'hi ' + name

with ThreadPoolExecutor(max_workers=2) as ex:
    f1 = ex.submit(greet, 'Ana')
    f2 = ex.submit(greet, 'Bob')
    print(f1.result())
    print(f2.result())

map til mange inddata

executor.map(func, iterable) kører funktionen på hvert element samtidigt og leverer resultaterne i samme rækkefølge som inddataene.

from concurrent.futures import ThreadPoolExecutor

def cube(n):
    return n ** 3

with ThreadPoolExecutor() as ex:
    results = ex.map(cube, range(5))
    print(list(results))

Styring af antallet af arbejdere

max_workers begrænser, hvor mange tråde der kører på én gang. Ved I/O-bundet arbejde kan du bruge flere arbejdere end antallet af CPU-kerner.

from concurrent.futures import ThreadPoolExecutor
import time

def io_task(n):
    time.sleep(0.05)
    return n

start = time.perf_counter()
with ThreadPoolExecutor(max_workers=4) as ex:
    print(list(ex.map(io_task, range(4))))
print('ran concurrently')

as_completed

as_completed(futures) leverer hvert Future-objekt, så snart det er færdigt, uanset rækkefølgen ved indsendelsen. Det er ideelt til at behandle resultater, så snart de ankommer.

from concurrent.futures import ThreadPoolExecutor, as_completed
import time

def work(n):
    time.sleep(0.01 * (3 - n))
    return n

with ThreadPoolExecutor() as ex:
    futures = [ex.submit(work, i) for i in range(3)]
    for f in as_completed(futures):
        print('finished', f.result())

Håndtering af undtagelser

Hvis en opgave udløser en undtagelse, gemmes den i dens Future og kastes igen, når du kalder .result(). Sæt kaldet ind i try/except.

from concurrent.futures import ThreadPoolExecutor

def risky(n):
    if n == 0:
        raise ValueError('cannot be zero')
    return 10 // n

with ThreadPoolExecutor() as ex:
    f = ex.submit(risky, 0)
    try:
        print(f.result())
    except ValueError as e:
        print('caught:', e)

map med flere argumenter

map accepterer flere itererbare samlinger og sætter dem sammen til argumenter, ligesom den indbyggede map.

from concurrent.futures import ThreadPoolExecutor

def add(a, b):
    return a + b

with ThreadPoolExecutor() as ex:
    print(list(ex.map(add, [1, 2, 3], [10, 20, 30])))

Indsamling af resultater i en Dict

Et almindeligt mønster er at knytte hvert Future-objekt tilbage til dets inddata, så du ved, hvilket resultat der hører til hvad, når du bruger as_completed.

from concurrent.futures import ThreadPoolExecutor, as_completed

def length(word):
    return len(word)

words = ['cat', 'tiger', 'ox']
with ThreadPoolExecutor() as ex:
    future_to_word = {ex.submit(length, w): w for w in words}
    out = {}
    for f in as_completed(future_to_word):
        out[future_to_word[f]] = f.result()
print(sorted(out.items()))

Nedlukning med kontekststyring

Når du bruger udføreren i en with-blok, kaldes shutdown() automatisk, og der ventes på, at alle ventende opgaver bliver færdige.

from concurrent.futures import ThreadPoolExecutor

def job(n):
    return n * 2

with ThreadPoolExecutor() as ex:
    futures = [ex.submit(job, i) for i in range(3)]
print('all tasks done after the with block')
print([f.result() for f in futures])

Kontrol af Future-tilstand

Et Future har .done() og .running(), så du kan kontrollere fremdriften uden at blokere.

from concurrent.futures import ThreadPoolExecutor

def quick(n):
    return n + 1

with ThreadPoolExecutor() as ex:
    f = ex.submit(quick, 41)
    result = f.result()
    print('done?', f.done())
    print('value:', result)

Hvornår skal du bruge den?

ThreadPoolExecutor er ideel til mange små I/O-bundne opgaver: HTTP-kald, fillæsninger og databaseforespørgsler. Brug i stedet ProcessPoolExecutor til CPU-bundet arbejde.

from concurrent.futures import ThreadPoolExecutor

urls = ['a', 'b', 'c']

def fetch(u):
    return 'fetched ' + u

with ThreadPoolExecutor(max_workers=3) as ex:
    for r in ex.map(fetch, urls):
        print(r)

Hurtigt tjek

Afprøv din forståelse af ThreadPoolExecutor.

Opsummering

Du har lært om ThreadPoolExecutor:

  • submit() returnerer en Future; map() kører over en iterabel i rækkefølge.
  • as_completed() giver futures efterhånden, som de bliver færdige.
  • Undtagelser bliver synlige via result().
  • with-blokken håndterer nedlukningen.

Næste emne: ægte parallelitet med multiprocessing.

Gratis at komme i gang

Lær Python med en AI-underviser — gratis

Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.

Kurser
76
Lektioner
320

Ofte stillede spørgsmål

Er lektionen “ThreadPoolExecutor” gratis?

Ja — hele teksten til “ThreadPoolExecutor” kan læses gratis her på nettet. Hvis du vil øve dig interaktivt med en indbygget kodeeditor og en AI-vejleder døgnet rundt og få adgang til resten af Python Academy-kurset, skal du opgradere til CoddyKit PRO. Python Academy-kurset indeholder 4 lektioner i alt.

Hvad lærer jeg i “ThreadPoolExecutor”?

Kør opgaver samtidigt Du øver dig i Python Academy med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.

Skal jeg have erfaring for at begynde på Python Academy?

Der kræves ingen tidligere erfaring. Python Academy på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 2 af 4.

Hvor lang tid tager lektionen “ThreadPoolExecutor”?

De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.

Kan jeg skrive og køre kode i denne Python Academy-lektion?

Ja. Alle Python Academy-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.

Alle lektioner i dette kursus

  1. Tråde og GIL
  2. ThreadPoolExecutor
  3. Grundlæggende om multiprocessing
  4. Sikker deling af data
← Tilbage til Python Academy