Python Academy · Lektion

ThreadPoolExecutor

Kör uppgifter samtidigt

Lektion 2 av 413 steg

ThreadPoolExecutor är en gratis lektion i Python Academy på CoddyKit. Detta är lektion 2 av 4. Ni kan läsa hela lektionen gratis nedan och sedan öva praktiskt i webbläsaren med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt. Den ingår i lärvägen för Python Academy, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Python Academy innehåller totalt 4 lektioner.

Varför en trådpool?

Att skapa och sammanfoga trådar manuellt är omständligt. concurrent.futures.ThreadPoolExecutor hanterar en pool med arbetstrådar åt dig och returnerar resultat på ett smidigt sätt.

from concurrent.futures import ThreadPoolExecutor

def square(n):
    return n * n

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

submit och Future

submit() schemalägger ett anrop och returnerar genast en Future. Anropa .result() på den för att hämta värdet; anropet blockerar tills värdet är klart.

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 för många indata

executor.map(func, iterable) kör funktionen på varje objekt samtidigt och ger resultaten i indatans ordning.

from concurrent.futures import ThreadPoolExecutor

def cube(n):
    return n ** 3

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

Styra antalet arbetstrådar

max_workers begränsar hur många trådar som körs samtidigt. För I/O-bundet arbete kan du använda fler arbetstrådar än antalet CPU-kärnor.

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) ger varje Future så snart den är klar, oavsett i vilken ordning de skickades in. Det passar utmärkt när du vill behandla resultaten så snart de kommer.

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())

Hantera undantag

Om en uppgift utlöser ett undantag lagras undantaget i dess Future och utlöses igen när du anropar .result(). Omslut anropet med 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)

Mappa med flera argument

map accepterar flera itererbara objekt och använder motsvarande värden som argument, precis som den inbyggda 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])))

Samla resultat i en dict

Ett vanligt mönster är att koppla varje Future till dess indata, så att du vet vilket resultat som hör till vilket indata när du använder 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()))

Avslut med kontexthanterare

Om du använder executor i ett with-block anropas shutdown() automatiskt, och programmet väntar på att alla väntande uppgifter ska slutföras.

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

Kontrollera Future-tillstånd

En Future tillhandahåller .done() och .running(), så att du kan kontrollera förloppet utan att blockera.

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)

När ska du använda det

ThreadPoolExecutor passar utmärkt för många små I/O-bundna uppgifter: HTTP-anrop, filläsning och databasfrågor. För CPU-bundet arbete använder du i stället ProcessPoolExecutor.

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)

Snabbtest

Testa förståelsen av ThreadPoolExecutor.

Sammanfattning

Ni har lärt Er ThreadPoolExecutor:

  • submit() returnerar en Future; map() körs över ett itererbart objekt i ordning.
  • as_completed() ger futures allt eftersom de blir klara.
  • Undantag blir synliga via result().
  • with-blocket hanterar avstängningen.

Nästa steg: verklig parallellism med multiprocessing.

Gratis att börja

Lär dig Python med en AI-lärare – gratis

Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.

Kurser
76
Lektioner
320

Vanliga frågor

Är lektionen ”ThreadPoolExecutor” gratis?

Ja – hela texten till ”ThreadPoolExecutor” kan läsas gratis här på webben. Om Ni vill öva interaktivt med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt och låsa upp resten av kursen i Python Academy, kan Ni uppgradera till CoddyKit PRO. Kursen i Python Academy innehåller totalt 4 lektioner.

Vad lär jag mig i ”ThreadPoolExecutor”?

Kör uppgifter samtidigt Ni övar på Python Academy med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.

Behöver jag någon erfarenhet för att börja lära mig Python Academy?

Du behöver inga förkunskaper. Utbildningen i Python Academy på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 2 av 4.

Hur lång tid tar lektionen ”ThreadPoolExecutor”?

De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.

Kan jag skriva och köra kod i den här Python Academy-lektionen?

Ja. Varje Python Academy-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.

Alla lektioner i den här kursen

  1. Trådar och GIL
  2. ThreadPoolExecutor
  3. Grunderna i multiprocessing
  4. Säker delning av data
← Tillbaka till Python Academy