Programmēšana

3 soļi līdz Python asinhronajam remontam

Python ir viena no daudzajām valodām, kas atbalsta zināmu veidu, kā rakstīt asinhronas programmas - programmas, kas brīvi pārslēdzas starp vairākiem uzdevumiem, kas darbojas vienlaikus, tāpēc neviens uzdevums neaptur citu progresu.

Iespējams, ka jūs galvenokārt esat rakstījis sinhronas Python programmas - programmas, kas vienlaikus veic tikai vienu lietu, gaidot katra uzdevuma pabeigšanu, pirms sākat citu. Pāreja uz asinhrono versiju var būt apgrūtinoša, jo tas prasa iemācīties ne tikai jaunu sintaksi, bet arī jaunus domāšanas veidus par savu kodu.

Šajā rakstā mēs izpētīsim, kā esošu, sinhronu programmu var pārvērst par asinhronu. Tas ietver ne tikai funkciju dekorēšanu ar asinhrono sintaksi; tas prasa arī domāt citādi par mūsu programmas darbību un izlemt, vai asinhronizācija ir pat laba metafora tam, ko tā dara.

[Arī vietnē: Uzziniet Python padomus un trikus no Serdara Jegulalpa viedajiem Python videoklipiem]

Kad Python lietot asinhronizāciju

Python programma ir vispiemērotākā asinhronizācijai, ja tai ir šādas īpašības:

  • Tas mēģina darīt kaut ko tādu, ko pārsvarā saista I / O vai gaidīt, kad kāds ārējs process būs pabeigts, piemēram, ilgstoši lasīts tīkls.
  • Tas mēģina veikt vienu vai vairākus šāda veida uzdevumus vienlaikus, iespējams, arī apstrādājot lietotāju mijiedarbību.
  • Attiecīgie uzdevumi nav skaitļošanas ziņā smagi.

Python programma, kas izmanto pavedienus, parasti ir laba kandidatūra asinhronizācijas izmantošanai. Vītnes Python ir kooperatīvas; viņi piekāpjas viens otram pēc vajadzības. Async uzdevumi Python darbojas tāpat. Turklāt async piedāvā noteiktas priekšrocības salīdzinājumā ar pavedieniem:

  • The asinhronais/gaidi sintakse atvieglo programmas asinhrono daļu identificēšanu. Turpretī bieži ir grūti īsumā pateikt, kuras lietotnes daļas darbojas pavedienā.
  • Tā kā asinhronajiem uzdevumiem ir viena un tā pati pavediens, visus datus, kuriem tie piekļūst, automātiski pārvalda GIL (Python vietējais mehānisms piekļuves sinhronizēšanai objektiem). Vītnēm bieži nepieciešami sarežģīti sinhronizācijas mehānismi.
  • Async uzdevumus ir vieglāk pārvaldīt un atcelt nekā pavedienus.

Async izmantošana ir ieteicams, ja jūsu Python programmai ir šādas īpašības:

  • Uzdevumiem ir augstas skaitļošanas izmaksas, piemēram, tie veic smagu skaitļu krokēšanu. Vislabāk tiek galā ar smagu skaitļošanas darbu daudzapstrāde, kas ļauj veltīt veselu aparatūra pavediens katram uzdevumam.
  • Uzdevumi nav savstarpēji saistīti. Ja katrs uzdevums ir atkarīgs no pēdējā, nav jēgas likt tiem darboties asinhroni. Tas nozīmē, ka, ja programma ietverkomplekti sērijveida uzdevumus, katru kopu var izpildīt asinhroni.

1. darbība: identificējiet programmas sinhronās un asinhronās daļas

Python asinhronais kods ir jāuzsāk un jāpārvalda jūsu Python lietojumprogrammas sinhronajām daļām. Šajā nolūkā jūsu pirmais uzdevums, pārveidojot programmu par asinhrono, ir novilkt līniju starp koda sinhronizācijas un asinhronizācijas daļām.

Mūsu iepriekšējā rakstā par asinhronizāciju mēs kā vienkāršu piemēru izmantojām tīmekļa skrāpēšanas lietotni. Koda asinhronās daļas ir rutīnas, kas atver tīkla savienojumus un nolasa no vietnes - viss, ko vēlaties savstarpēji sapludināt. Bet tā programmas daļa, kas to visu iedarbina, nav asinhrona; tas palaiž asinhronos uzdevumus un pēc tam tos graciozi aizver, kad tie ir pabeigti.

Ir arī svarīgi nošķirt visus iespējamosbloķēšanas darbība no asinhronizācijas un saglabājiet to savas lietotnes sinhronizācijas daļā. Piemēram, nolasot lietotāja ievadi no konsoles, tiek bloķēts viss, ieskaitot asinhrono notikumu loku. Tādēļ jūs vēlaties apstrādāt lietotāja ievadi vai nu pirms asinhrono uzdevumu palaišanas, vai pēc to pabeigšanas. (Tā ir iespējams sinhroni apstrādāt lietotāja ievadi, izmantojot daudzapstrādi vai pavedienus, taču tas ir uzlabots uzdevums, kurā mēs šeit neiekļausimies.)

Daži bloķēšanas darbību piemēri:

  • Konsoles ievade (kā mēs tikko aprakstījām).
  • Uzdevumi, kas saistīti ar lielu CPU izmantošanu.
  • Izmantojot laiks.miega piespiest pauzi. Ņemiet vērā, ka jūs varat gulēt asinhronās funkcijas iekšpusē, izmantojot asyncio.miega kā aizstājēju laiks.miega.

2. darbība. Konvertējiet atbilstošās sinhronizācijas funkcijas par asinhronizācijas funkcijām

Kad zināt, kuras programmas daļas darbosies asinhroni, varat tās sadalīt funkcijās (ja vēl neesat to izdarījis) un pārvērst par asinhronajām funkcijām ar asinhronais atslēgvārds. Pēc tam jums būs jāpievieno kods lietojumprogrammas sinhronajai daļai, lai palaistu asinhrono kodu un, ja nepieciešams, apkopotu tā rezultātus.

Piezīme. Jūs vēlaties pārbaudīt katras asinhronās funkcijas izsaukuma ķēdi un pārliecināties, ka tās neizsauc potenciāli ilgstošu vai bloķējošu darbību. Async funkcijas var tieši izsaukt sinhronizācijas funkcijas, un, ja šī sinhronizācijas funkcija tiek bloķēta, tad arī asinhronā funkcija to izsauc.

Apskatīsim vienkāršotu piemēru, kā var darboties sinhronizācija ar asinhrono reklāmguvumu. Šeit ir mūsu programma “pirms”:

def a_function (): # kāda ar asinhronu saderīga darbība, kas aizņem kādu laiku def another_function (): # kāda sinhronizācijas funkcija, bet ne bloķējoša def def___default (): a_function () another_function () def main (): par _ diapazonā (3): do_stuff () main () 

Ja mēs vēlamies trīs gadījumus do_ stuff lai palaistu kā asinhronus uzdevumus, mums ir jāgriežas do_ stuff (un, iespējams, visu, kam tas skar) asinhronajā kodā. Šī ir pirmā pāreja uz reklāmguvumu:

importēt asyncio async def a_function (): # dažas ar async saderīgas darbības, kas prasa laiku def another_function (): # kāda sinhronizācijas funkcija, bet ne bloķējoša async def do_stuff (): gaida a_function () another_function () async def main ( ): uzdevumi = [] _ ​​diapazonā (3): task.append (asyncio.create_task (do_stuff ())) gaida asyncio.gather (uzdevumi) asyncio.run (main ()) 

Ievērojiet mūsu veiktās izmaiņasgalvenais. Tagad galvenais izmanto asinsija lai palaistu katru do_ stuff kā vienlaikus uzdevumu, tad gaida rezultātus (asyncio.gather). Mēs arī pārveidojām a_funkcija asinhronajā funkcijā, jo mēs vēlamies visus a_funkcija darboties blakus un citām funkcijām, kurām nepieciešama asinhronā uzvedība.

Ja mēs gribētu iet soli tālāk, mēs varētu arī pievērsties cits_funkcija asinhronizēt:

async def another_function (): # kaut kāda sinhronizācijas funkcija, bet ne bloķējošā async def do_stuff (): gaidiet 

Tomēr padarotcits_funkcija asinhronais būtu pārspīlēts, jo (kā jau esam atzīmējuši) tas nedara neko tādu, kas bloķētu mūsu programmas progresu. Arī tad, ja tiek sauktas kādas sinhronas mūsu programmas daļascits_funkcija, mums tie būtu jāpārvērš arī par asinhroniem, kas mūsu programmu varētu padarīt sarežģītāku nekā vajadzētu.

3. darbība: rūpīgi pārbaudiet savu Python asinhrono programmu

Jebkura asinhronizētā programma ir jāpārbauda pirms tās nonākšanas ražošanā, lai nodrošinātu, ka tā darbojas, kā paredzēts.

Ja jūsu programma ir neliela apjoma - teiksim, apmēram pāris desmiti rindiņu - un tai nav nepieciešams pilns testa komplekts, tad nevajadzētu būt grūti pārbaudīt, vai tā darbojas kā paredzēts. Tas nozīmē, ka, ja jūs pārveidojat programmu par asinhronu kā daļu no lielāka projekta, kur testa komplekts ir standarta stiprinājums, ir lietderīgi rakstīt vienības testus gan asinhroniem, gan sinhronizācijas komponentiem.

Abās galvenajās Python testa ietvarās tagad ir sava veida asinhronais atbalsts. Pītona pašavienoti ietvars ietver testa gadījuma objektus asinhronajām funkcijām un pytest piedāvāpytest-asyncio tiem pašiem mērķiem.

Visbeidzot, rakstot asinhrono komponentu testus, testu nosacījums būs jārisina ar to asinhronumu. Piemēram, nav garantijas, ka asinhronie darbi tiks pabeigti iesniegtajā secībā. Pirmais varētu nākt pēdējais, un daži, iespējams, vispār nekad nepabeigs. Visos testos, kurus projektējat asinhronajai funkcijai, ir jāņem vērā šīs iespējas.

Kā darīt vairāk ar Python

  • Sāciet darbu ar asinhronizāciju Python
  • Kā lietot asyncio Python
  • Kā izmantot PyInstaller, lai izveidotu Python izpildāmos failus
  • Cython apmācība: kā paātrināt Python
  • Kā instalēt Python viedajā veidā
  • Kā pārvaldīt Python projektus, izmantojot dzeju
  • Kā pārvaldīt Python projektus ar Pipenv
  • Virtualenv un venv: paskaidrotas virtuālās Python vides
  • Python virtualenv un venv do's un don'ts
  • Paskaidrots Python vītne un apakšprocesi
  • Kā izmantot Python atkļūdotāju
  • Kā izmantot Timeit, lai profilētu Python kodu
  • Kā izmantot cProfile Python koda profilēšanai
  • Kā konvertēt Python uz JavaScript (un atkal atpakaļ)
$config[zx-auto] not found$config[zx-overlay] not found