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
Truekommer händelseslingan att köras i debug-läge.Falseinaktiverar debug-läget explicit.Noneanvänds för att respektera de globala inställningarna för Felsökningsläge.Om loop_factory inte är
Noneanvä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.EventLoopkan 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
Nonesom 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
Truekommer händelseslingan att köras i debug-läge.Falseinaktiverar debug-läget explicit.Noneanvä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.Contextför koden som ska köras i. Om context ärNoneanvä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
Runneranvänder strategin lazy initialization, dess konstruktör initierar inte underliggande strukturer på låg nivå.Inbäddade loop och context skapas vid
withbody 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.Runnerskapar en huvuduppgift för den passerade coroutinen för dess exekvering.När
signal.SIGINTgenereras av Ctrl-C, avbryter den anpassade signalhanteraren huvuduppgiften genom att anropaasyncio.Task.cancel()som genererarasyncio.CancelledErrorinuti huvuduppgiften. Detta gör att Python-stacken rullas upp,try/exceptochtry/finallyblock 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 tillKeyboardInterruptutan att avbryta huvuduppgiften.