Löpare¶
Källkod: Lib/asyncio/runners.py
I detta avsnitt beskrivs asyncioprimitiver på hög nivå för att köra asynciokod.
De är byggda ovanpå en event loop med målet att förenkla asynkron kodanvändning för vanliga, utbredda scenarier.
Kör ett asyncioprogram¶
- asyncio.run(coro, *, debug=None, loop_factory=None)¶
Kör coro i en asynciohändelseslinga och returnera resultatet.
Argumentet kan vara vilket väntande objekt som helst.
Denna funktion kör awaitable och tar hand om hanteringen av asynciohändelseslingan, finaliserar asynkrona generatorer och stänger exekutorn.
Denna funktion kan inte anropas när en annan asyncio-händelseslinga körs i samma tråd.
Om debug är
True
kommer händelseslingan att köras i debug-läge.False
inaktiverar debug-läget explicit.None
används för att respektera de globala inställningarna för Felsökningsläge.Om loop_factory inte är
None
används den för att skapa en ny händelseslinga; annars användsasyncio.new_event_loop()
. Slingan stängs i slutet. Denna funktion bör användas som en huvudingångspunkt för asyncioprogram och bör helst bara anropas en gång. Det rekommenderas att använda loop_factory för att konfigurera händelseslingan i stället för policies. Genom att skickaasyncio.EventLoop
kan man köra asyncio utan policysystemet.Exekveraren får en timeout på 5 minuter för att stängas av. Om exekveraren inte har avslutats inom denna tid utfärdas en varning och exekveraren stängs.
Exempel:
async def main(): await asyncio.sleep(1) skriv ut('hello') asyncio.run(main())
Tillagd i version 3.7.
Ändrad i version 3.9: Uppdaterad för att använda
loop.shutdown_default_executor()
.Ändrad i version 3.10: debug är
None
som standard för att respektera de globala inställningarna för felsökningsläget.Ändrad i version 3.12: Lagt till parametern loop_factory.
Ändrad i version 3.14: coro kan vara vilket väntande objekt som helst.
Anteckning
Policysystemet
asyncio
är föråldrat och kommer att tas bort i Python 3.16; från och med då behövs en explicit loop_factory för att konfigurera händelseslingan.
Kontexthanterare för löpare¶
- class asyncio.Runner(*, debug=None, loop_factory=None)¶
En kontexthanterare som förenklar flera asynkrona funktionsanrop i samma kontext.
Ibland bör flera asynkrona funktioner på toppnivå anropas i samma event loop och
contextvars.Context
.Om debug är
True
kommer händelseslingan att köras i debug-läge.False
inaktiverar debug-läget explicit.None
används för att respektera de globala inställningarna för Felsökningsläge.loop_factory kan användas för att åsidosätta skapandet av slingan. Det är loop_factory:s ansvar att ställa in den skapade loopen som den aktuella. Som standard används
asyncio.new_event_loop()
och ställs in som aktuell händelseslinga medasyncio.set_event_loop()
om loop_factory ärNone
.I grund och botten kan
asyncio.run()
-exemplet skrivas om med runner-användningen:async def main(): await asyncio.sleep(1) skriv ut('hello') med asyncio.Runner() som runner: runner.run(main())
Tillagd i version 3.11.
- run(coro, *, context=None)¶
Exekvera coro i den inbäddade händelseslingan.
Argumentet kan vara vilket väntande objekt som helst.
Om argumentet är en coroutine paketeras det in i en Task.
Ett valfritt argument context som endast innehåller nyckelord gör det möjligt att ange en anpassad
contextvars.Context
för koden som ska köras i. Om context ärNone
används löparens standardkontext.Returnerar awaitable-resultatet eller skapar ett undantag.
Denna funktion kan inte anropas när en annan asyncio-händelseslinga körs i samma tråd.
Ändrad i version 3.14: coro kan vara vilket väntande objekt som helst.
- close()¶
Stäng löparen.
Slutför asynkrona generatorer, stäng av standardutföraren, stäng händelseslingan och släpp inbäddade
contextvars.Context
.
- get_loop()¶
Returnerar den händelseslinga som är associerad med runner-instansen.
Anteckning
Runner
använder strategin lazy initialization, dess konstruktör initierar inte underliggande strukturer på låg nivå.Inbäddade loop och context skapas vid
with
body entry eller vid första anropet avrun()
ellerget_loop()
.
Hantering av tangentbordsavbrott¶
Tillagd i version 3.11.
När signal.SIGINT
utlöses av Ctrl-C, utlöses KeyboardInterrupt
undantag i huvudtråden som standard. Detta fungerar dock inte med asyncio
eftersom det kan avbryta asyncio-interna funktioner och kan hindra programmet från att avslutas.
För att mildra detta problem hanterar asyncio
signal.SIGINT
på följande sätt:
asyncio.Runner.run()
installerar en anpassadsignal.SIGINT
-hanterare innan någon användarkod exekveras och tar bort den när funktionen avslutas.Runner
skapar en huvuduppgift för den passerade coroutinen för dess exekvering.När
signal.SIGINT
genereras av Ctrl-C, avbryter den anpassade signalhanteraren huvuduppgiften genom att anropaasyncio.Task.cancel()
som genererarasyncio.CancelledError
inuti huvuduppgiften. Detta gör att Python-stacken rullas upp,try/except
ochtry/finally
block kan användas för resursrensning. Efter att huvuduppgiften har avbrutits gerasyncio.Runner.run()
upphov tillKeyboardInterrupt
.En användare kan skriva en tät loop som inte kan avbrytas av
asyncio.Task.cancel()
, i vilket fall den andra följande Ctrl-C omedelbart ger upphov tillKeyboardInterrupt
utan att avbryta huvuduppgiften.