concurrent.futures — Starta parallella uppgifter

Tillagd i version 3.2.

Källkod: Lib/concurrent/futures/thread.py, Lib/concurrent/futures/process.py, och Lib/concurrent/futures/interpreter.py


Modulen concurrent.futures tillhandahåller ett gränssnitt på hög nivå för asynkron exekvering av anropbara filer.

Den asynkrona exekveringen kan utföras med trådar, med hjälp av ThreadPoolExecutor eller InterpreterPoolExecutor, eller separata processer, med hjälp av ProcessPoolExecutor. Alla implementerar samma gränssnitt, som definieras av den abstrakta klassen Executor.

Tillgänglighet: not WASI.

Den här modulen fungerar inte eller är inte tillgänglig på WebAssembly. Se WebAssembly-plattformar för mer information.

Exekverande objekt

class concurrent.futures.Executor

En abstrakt klass som tillhandahåller metoder för att exekvera anrop asynkront. Den bör inte användas direkt, utan genom sina konkreta underklasser.

submit(fn, /, *args, **kwargs)

Schemalägger anropbarheten fn så att den exekveras som fn(*args, **kwargs) och returnerar ett Future-objekt som representerar exekveringen av anropbarheten.

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)

Liknar map(fn, *iterables) förutom:

  • iterables samlas in omedelbart och inte slentrianmässigt, såvida inte en buffersize har angetts för att begränsa antalet inlämnade uppgifter vars resultat ännu inte har hämtats. Om bufferten är full pausas iterationen över iterables tills ett resultat hämtas från bufferten.

  • fn exekveras asynkront och flera anrop till fn kan göras samtidigt.

Den returnerade iteratorn ger upphov till ett TimeoutError om __next__() anropas och resultatet inte är tillgängligt efter timeout sekunder från det ursprungliga anropet till Executor.map(). timeout kan vara en int eller en float. Om timeout inte anges eller None, finns det ingen gräns för väntetiden.

Om ett fn-anrop ger upphov till ett undantag, kommer detta undantag att uppstå när dess värde hämtas från iteratorn.

När ProcessPoolExecutor används, delar denna metod upp iterables i ett antal bitar som sedan skickas till poolen som separata uppgifter. Den (ungefärliga) storleken på dessa bitar kan anges genom att chunksize sätts till ett positivt heltal. För mycket långa iterabler kan ett stort värde för chunksize förbättra prestandan avsevärt jämfört med standardstorleken 1. Med ThreadPoolExecutor och InterpreterPoolExecutor har chunksize ingen effekt.

Ändrad i version 3.5: Lagt till parametern chunksize.

Ändrad i version 3.14: Parametern buffersize har lagts till.

shutdown(wait=True, *, cancel_futures=False)

Signalerar till exekutorn att den ska frigöra alla resurser som den använder när de aktuella väntande futures är klara med exekveringen. Anrop till Executor.submit() och Executor.map() som görs efter nedstängning kommer att ge upphov till RuntimeError.

Om wait är True kommer denna metod inte att returneras förrän alla väntande futures har exekverats och de resurser som är associerade med exekveraren har frigjorts. Om wait är False kommer denna metod att returneras omedelbart och resurserna som är associerade med exekveraren kommer att frigöras när alla väntande futures har exekverats. Oavsett värdet på wait kommer hela Python-programmet inte att avslutas förrän alla väntande futures har exekverats.

Om cancel_futures är True, kommer denna metod att avbryta alla väntande futures som exekutören inte har börjat köra. Eventuella terminer som är avslutade eller körs kommer inte att annulleras, oavsett värdet på cancel_futures.

Om både cancel_futures och wait är True, kommer alla futures som exekutorn har börjat köra att slutföras innan denna metod återkommer. De återstående futures avbryts.

Du kan undvika att behöva anropa denna metod explicit om du använder with-satsen, som kommer att stänga av Executor (väntar som om Executor.shutdown() anropades med wait satt till True):

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

Ändrad i version 3.9: Lagt till cancel_futures.

ThreadPool-utförare

ThreadPoolExecutor är en Executor-underklass som använder en pool av trådar för att utföra anrop asynkront.

Dödlägen kan uppstå när den anropbara funktionen som är associerad med en Future väntar på resultatet av en annan Future. Till exempel:

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)

Och:

def vänta_på_framtiden():
    f = executor.submit(pow, 5, 2)
    # Detta kommer aldrig att slutföras eftersom det bara finns en arbetstråd och
    # den utför den här funktionen.
    print(f.resultat())

executor = ThreadPoolExecutor(max_workers=1)
executor.submit(vänta_på_framtiden)
class concurrent.futures.ThreadPoolExecutor(max_workers=None, thread_name_prefix='', initializer=None, initargs=())

En Executor-underklass som använder en pool med högst max_workers trådar för att utföra anrop asynkront.

Alla trådar som står i kö till ThreadPoolExecutor kommer att sammanfogas innan tolken kan avslutas. Observera att den exit-hanterare som gör detta exekveras före alla exit-hanterare som läggs till med atexit. Detta innebär att undantag i huvudtråden måste fångas upp och hanteras för att kunna signalera till trådarna att de ska avslutas på ett elegant sätt. Av denna anledning rekommenderas det att ThreadPoolExecutor inte används för långvariga uppgifter.

initializer är en valfri callable som anropas i början av varje arbetstråd; initargs är en tupel av argument som skickas till initializern. Om initializer ger upphov till ett undantag kommer alla pågående jobb att ge upphov till en BrokenThreadPool, liksom alla försök att skicka fler jobb till poolen.

Ändrad i version 3.5: Om max_workers är None eller inte anges, kommer det som standard att vara antalet processorer på maskinen, multiplicerat med 5, förutsatt att ThreadPoolExecutor ofta används för att överlappa I/O istället för CPU-arbete och antalet workers bör vara högre än antalet workers för ProcessPoolExecutor.

Ändrad i version 3.6: Parametern thread_name_prefix har lagts till så att användare kan styra threading.Thread -namnen för arbetstrådar som skapas av poolen för enklare felsökning.

Ändrad i version 3.7: Lagt till argumenten initializer och initargs.

Ändrad i version 3.8: Standardvärdet för max_workers ändras till min(32, os.cpu_count() + 4). Detta standardvärde bevarar minst 5 arbetare för I/O-bundna uppgifter. Det använder högst 32 CPU-kärnor för CPU-bundna uppgifter som frigör GIL. Och det undviker att använda mycket stora resurser implicit på flerkärniga maskiner.

ThreadPoolExecutor återanvänder nu inaktiva arbetstrådar innan max_workers arbetstrådar också startas.

Ändrad i version 3.13: Standardvärdet för max_workers ändras till min(32, (os.process_cpu_count() or 1) + 4).

ThreadPoolExecutor Exempel

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

Utförare av tolkPool

Klassen InterpreterPoolExecutor använder en pool av tolkar för att exekvera anrop asynkront. Det är en ThreadPoolExecutor-underklass, vilket innebär att varje arbetare körs i sin egen tråd. Skillnaden här är att varje arbetare har sin egen tolk och kör varje uppgift med hjälp av den tolken.

Den största fördelen med att använda tolkar i stället för enbart trådar är den verkliga parallelliteten med flera kärnor. Varje tolk har sin egen Global Interpreter Lock, så kod som körs i en tolk kan köras på en CPU-kärna, medan kod i en annan tolk körs oblockerad på en annan kärna.

Avvägningen är att det kan kräva extra ansträngning att skriva samtidig kod för användning med flera tolkar. Detta beror dock på att man tvingas vara medveten om hur och när tolkarna interagerar och att man måste vara tydlig med vilka data som delas mellan tolkarna. Detta resulterar i flera fördelar som hjälper till att balansera den extra ansträngningen, inklusive äkta flerkärnig parallellism, Till exempel kan kod som skrivs på det här sättet göra det lättare att resonera om samtidighet. En annan stor fördel är att du inte behöver ta itu med flera av de stora smärtpunkterna med att använda trådar, som race conditions.

Varje arbetares tolk är isolerad från alla andra tolkar. ”Isolerad” betyder att varje tolk har sitt eget runtime-tillstånd och fungerar helt oberoende. Om du till exempel omdirigerar sys.stdout i en tolk, kommer den inte att omdirigeras automatiskt till någon annan tolk. Om du importerar en modul i en tolk importeras den inte automatiskt i någon annan tolk. Du måste importera modulen separat i den tolk där du behöver den. Faktum är att varje modul som importeras i en tolk är ett helt separat objekt från samma modul i en annan tolk, inklusive sys, builtins och till och med __main__.

Isolering innebär att ett föränderligt objekt, eller andra data, inte kan användas av mer än en tolk samtidigt. Det innebär i praktiken att tolkarna inte kan dela sådana objekt eller data. Istället måste varje tolk ha sin egen kopia, och du måste synkronisera eventuella ändringar mellan kopiorna manuellt. Oföränderliga objekt och data, som de inbyggda singletonerna, strängarna och tuplerna av oföränderliga objekt, har inte dessa begränsningar.

Kommunikation och synkronisering mellan tolkar görs mest effektivt med hjälp av dedikerade verktyg, som de som föreslås i PEP 734. Ett mindre effektivt alternativ är att serialisera med pickle och sedan skicka bytena över en delad socket eller pipe.

class concurrent.futures.InterpreterPoolExecutor(max_workers=None, thread_name_prefix='', initializer=None, initargs=())

En ThreadPoolExecutor-underklass som utför anrop asynkront med hjälp av en pool med högst max_workers trådar. Varje tråd kör uppgifter i sin egen tolk. De arbetande tolkarna är isolerade från varandra, vilket innebär att var och en har sitt eget körtidstillstånd och att de inte kan dela några föränderliga objekt eller andra data. Varje tolk har sitt eget Global Interpreter Lock, vilket innebär att kod som körs med den här exekutorn har äkta parallellitet med flera kärnor.

De valfria argumenten initializer och initargs har samma betydelse som för ThreadPoolExecutor: initialiseraren körs när varje arbetare skapas, men i det här fallet körs den i arbetarens tolk. Exekutorn serialiserar initialiseraren och initargs med pickle när den skickar dem till arbetarens tolk.

Anteckning

Exekveraren kan ersätta undantag från initialiserare med ExecutionFailed.

Andra varningar från överordnad ThreadPoolExecutor gäller här.

submit() och map() fungerar som vanligt, förutom att arbetaren serialiserar anropsbarnet och argumenten med pickle när de skickas till dess tolk. På samma sätt serialiserar arbetaren returvärdet när det skickas tillbaka.

När en arbetares aktuella uppgift ger upphov till ett undantag som inte fångats upp, försöker arbetaren alltid att bevara undantaget som det är. Om det lyckas sätts även __cause__ till en motsvarande ExecutionFailed-instans, som innehåller en sammanfattning av det ursprungliga undantaget. I det ovanliga fallet att arbetaren inte kan bevara originalet som det är, bevarar den direkt motsvarande ExecutionFailed-instans istället.

ProcessPoolExekutör

Klassen ProcessPoolExecutor är en underklass till Executor som använder en pool av processer för att exekvera anrop asynkront. ProcessPoolExecutor använder modulen multiprocessing, vilket gör att den kan kringgå Global Interpreter Lock, men innebär också att endast picklbara objekt kan exekveras och returneras.

Modulen __main__ måste kunna importeras av underprocesser som arbetar. Detta innebär att ProcessPoolExecutor inte kommer att fungera i den interaktiva tolken.

Anrop av Executor eller Future metoder från en callable som skickats till en ProcessPoolExecutor kommer att resultera i deadlock.

Observera att restriktionerna för funktioner och argument som måste kunna betas enligt multiprocessing.Process gäller när man använder submit() och map() på en ProcessPoolExecutor. En funktion som definieras i en REPL eller en lambda bör inte förväntas fungera.

class concurrent.futures.ProcessPoolExecutor(max_workers=None, mp_context=None, initializer=None, initargs=(), max_tasks_per_child=None)

En Executor-underklass som utför anrop asynkront med hjälp av en pool med högst max_workers processer. Om max_workers är None eller inte anges, kommer det som standard att vara os.process_cpu_count(). Om max_workers är mindre än eller lika med 0, så kommer ett ValueError att uppstå. I Windows måste max_workers vara mindre än eller lika med 61. Om den inte är det kommer ett ValueError att visas. Om max_workers är None kommer standardvärdet att vara högst 61, även om fler processorer är tillgängliga. mp_context kan vara en multiprocessing-kontext eller None. Det kommer att användas för att starta arbetarna. Om mp_context är None eller inte anges, används standardkontexten multiprocessing. Se Sammanhang och startmetoder.

initializer är en valfri callable som anropas i början av varje arbetsprocess; initargs är en tupel av argument som skickas till initializern. Om initializer ger upphov till ett undantag kommer alla pågående jobb att ge upphov till en BrokenProcessPool, liksom alla försök att skicka fler jobb till poolen.

max_tasks_per_child är ett valfritt argument som anger det maximala antalet uppgifter som en enskild process kan utföra innan den avslutas och ersätts med en ny arbetsprocess. Som standard är max_tasks_per_child None vilket innebär att arbetsprocesserna kommer att leva lika länge som poolen. När ett maxvärde anges kommer startmetoden ”spawn” för multiprocessing att användas som standard om det inte finns någon parameter mp_context. Denna funktion är inte kompatibel med startmetoden ”fork”.

Ändrad i version 3.3: När en av arbetsprocesserna avslutas abrupt, genereras nu ett BrokenProcessPool-fel. Tidigare var beteendet odefinierat, men operationer på exekveraren eller dess futures frös ofta eller blockerades.

Ändrad i version 3.7: Argumentet mp_context lades till för att användare ska kunna styra startmetoden för arbetsprocesser som skapas av poolen.

Lagt till argumenten initializer och initargs.

Ändrad i version 3.11: Argumentet max_tasks_per_child lades till så att användarna kan styra livslängden för arbetarna i poolen.

Ändrad i version 3.12: På POSIX-system, om din applikation har flera trådar och multiprocessing-kontexten använder startmetoden "fork": Funktionen os.fork() som anropas internt för att skapa arbetare kan ge upphov till en DeprecationWarning. Skicka en mp_context som är konfigurerad att använda en annan startmetod. Se dokumentationen för os.fork() för ytterligare förklaring.

Ändrad i version 3.13: max_workers använder os.process_cpu_count() som standard, istället för os.cpu_count().

Ändrad i version 3.14: Standardmetoden för processstart (se Sammanhang och startmetoder) ändrades bort från fork. Om du kräver startmetoden fork för ProcessPoolExecutor måste du uttryckligen skicka mp_context=multiprocessing.get_context("fork").

terminate_workers()

Försök att avsluta alla levande arbetsprocesser omedelbart genom att anropa Process.terminate på var och en av dem. Internt kommer den också att anropa Executor.shutdown() för att säkerställa att alla andra resurser som är associerade med exekveraren frigörs.

Efter anrop av denna metod ska den som anropar inte längre skicka uppdrag till utföraren.

Tillagd i version 3.14.

kill_workers()

Försök att döda alla levande arbetsprocesser omedelbart genom att anropa Process.kill på var och en av dem. Internt kommer den också att anropa Executor.shutdown() för att säkerställa att alla andra resurser som är associerade med exekveraren frigörs.

Efter anrop av denna metod ska den som anropar inte längre skicka uppdrag till utföraren.

Tillagd i version 3.14.

Exempel på 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()

Framtida objekt

Klassen Future kapslar in den asynkrona exekveringen av en anropsbar. Instanser av Future skapas av Executor.submit().

class concurrent.futures.Future

Kapslar in den asynkrona exekveringen av en callable. Future-instanser skapas av Executor.submit() och bör inte skapas direkt utom för testning.

cancel()

Försök att avbryta anropet. Om anropet håller på att utföras eller har avslutats och inte kan avbrytas kommer metoden att returnera False, annars kommer anropet att avbrytas och metoden kommer att returnera True.

cancelled()

Returnerar True om samtalet framgångsrikt har avbrutits.

running()

Returnerar True om anropet håller på att utföras och inte kan avbrytas.

done()

Returnerar True om anropet framgångsrikt avbröts eller avslutades.

result(timeout=None)

Returnerar det värde som anropet returnerade. Om anropet ännu inte har slutförts kommer denna metod att vänta upp till timeout sekunder. Om anropet inte har slutförts inom timeout sekunder, kommer ett TimeoutError att uppstå. timeout kan vara en int eller float. Om timeout inte anges eller om None, finns det ingen gräns för väntetiden.

Om framtiden avbryts innan den har slutförts kommer CancelledError att tas upp.

Om anropet gav upphov till ett undantag kommer denna metod att ge upphov till samma undantag.

exception(timeout=None)

Returnerar det undantag som uppstod vid anropet. Om anropet ännu inte har slutförts kommer denna metod att vänta upp till timeout sekunder. Om anropet inte har slutförts inom timeout sekunder, kommer ett TimeoutError att uppstå. timeout kan vara en int eller float. Om timeout inte anges eller om None, finns det ingen gräns för väntetiden.

Om framtiden avbryts innan den har slutförts kommer CancelledError att tas upp.

Om anropet slutfördes utan att någon fråga ställdes återsänds None.

add_done_callback(fn)

Kopplar den anropsbara fn till framtiden. fn kommer att anropas, med framtiden som enda argument, när framtiden avbryts eller slutar att köras.

Tillagda anropsbara filer anropas i den ordning de lades till och anropas alltid i en tråd som tillhör den process som lade till dem. Om anropsbarheten ger upphov till en Exception-subklass loggas den och ignoreras. Om anropet ger upphov till en subklass av BaseException är beteendet odefinierat.

Om framtiden redan har avslutats eller avbrutits, kommer fn att anropas omedelbart.

Följande Future-metoder är avsedda att användas i enhetstester och Executor-implementationer.

set_running_or_notify_cancel()

Denna metod bör endast anropas av Executor-implementationer innan de utför det arbete som är associerat med Future och av enhetstester.

Om metoden returnerar False så avbröts Future, dvs Future.cancel() anropades och returnerade True. Alla trådar som väntar på att Future ska slutföras (t.ex. genom as_completed() eller wait()) kommer att väckas.

Om metoden returnerar True så har Future inte avbrutits och har satts i drift, d.v.s. anrop till Future.running() kommer att returnera True.

Denna metod kan bara anropas en gång och kan inte anropas efter att Future.set_result() eller Future.set_exception() har anropats.

set_result(result)

Ställer in resultatet av det arbete som är associerat med Future till result.

Denna metod bör endast användas av Executor-implementationer och enhetstester.

Ändrad i version 3.8: Denna metod ger upphov till concurrent.futures.InvalidStateError om Future redan är klar.

set_exception(exception)

Ställer in resultatet av det arbete som associeras med Future till Exception exception.

Denna metod bör endast användas av Executor-implementationer och enhetstester.

Ändrad i version 3.8: Denna metod ger upphov till concurrent.futures.InvalidStateError om Future redan är klar.

Modulens funktioner

concurrent.futures.wait(fs, timeout=None, return_when=ALL_COMPLETED)

Vänta på att Future-instanser (eventuellt skapade av olika Executor-instanser) som ges av fs ska slutföras. Duplicerade futures som ges till fs tas bort och returneras endast en gång. Returnerar en namngiven 2-tupel av uppsättningar. Den första uppsättningen, med namnet done, innehåller de futures som slutfördes (finished eller cancelled futures) innan väntan slutfördes. Den andra uppsättningen, med namnet not_done, innehåller de terminer som inte slutfördes (väntande eller pågående terminer).

timeout kan användas för att styra det maximala antalet sekunder som ska väntas innan returnering. timeout kan vara en int eller float. Om timeout inte anges eller om None, finns det ingen gräns för väntetiden.

return_when anger när denna funktion ska returnera. Den måste vara en av följande konstanter:

Konstant

Beskrivning

concurrent.futures.FIRST_COMPLETED

Funktionen kommer att återkomma när någon framtid avslutas eller avbryts.

concurrent.futures.FIRST_EXCEPTION

Funktionen återkommer när en framtid avslutas genom att ett undantag utlöses. Om ingen framtid ger upphov till ett undantag så är det likvärdigt med ALL_COMPLETED.

concurrent.futures.ALL_COMPLETED

Funktionen återkommer när alla terminer är avslutade eller avbrutna.

concurrent.futures.as_completed(fs, timeout=None)

Returnerar en iterator över Future-instanser (eventuellt skapade av olika Executor-instanser) som ges av fs som ger futures när de slutförs (färdiga eller avbrutna futures). Alla futures som ges av fs och som är duplicerade kommer att returneras en gång. Alla futures som slutförts innan as_completed() anropas kommer att returneras först. Den returnerade iteratorn ger upphov till ett TimeoutError om __next__() anropas och resultatet inte är tillgängligt efter timeout sekunder från det ursprungliga anropet till as_completed(). timeout kan vara en int eller float. Om timeout inte anges eller None, finns det ingen gräns för väntetiden.

Se även

PEP 3148 – futures - utföra beräkningar asynkront

Förslaget som beskrev denna funktion för inkludering i Pythons standardbibliotek.

Undantagsklasser

exception concurrent.futures.CancelledError

Utlöses när en framtid avbryts.

exception concurrent.futures.TimeoutError

Ett föråldrat alias för TimeoutError, som uppstår när en framtida operation överskrider den angivna tidsgränsen.

Ändrad i version 3.11: Denna klass gjordes till ett alias för TimeoutError.

exception concurrent.futures.BrokenExecutor

Denna undantagsklass härstammar från RuntimeError och uppstår när en exekverare av någon anledning inte fungerar och inte kan användas för att skicka in eller utföra nya uppgifter.

Tillagd i version 3.7.

exception concurrent.futures.InvalidStateError

Utlöses när en operation utförs på en future som inte är tillåten i det aktuella tillståndet.

Tillagd i version 3.8.

exception concurrent.futures.thread.BrokenThreadPool

Denna undantagsklass härstammar från BrokenExecutor och uppstår när en av arbetarna i en ThreadPoolExecutor inte har initierats.

Tillagd i version 3.7.

exception concurrent.futures.interpreter.BrokenInterpreterPool

Denna undantagsklass härstammar från BrokenThreadPool och uppstår när en av arbetarna i en InterpreterPoolExecutor inte har initierats.

Tillagd i version 3.14.

exception concurrent.futures.interpreter.ExecutionFailed

Utlöses från InterpreterPoolExecutor när den givna initialiseraren misslyckas eller från submit() när det finns ett undantag som inte fångats upp från den inlämnade uppgiften.

Tillagd i version 3.14.

exception concurrent.futures.process.BrokenProcessPool

Denna undantagsklass härstammar från BrokenExecutor (tidigare RuntimeError) och uppstår när en av arbetarna i en ProcessPoolExecutor har avslutats på ett felaktigt sätt (t.ex. om den dödades från utsidan).

Tillagd i version 3.3.