Forum » Programiranje » Python primer async/await
Python primer async/await
marjan_h ::
Za primer razumevanja sem napisal majhen program v Pythonu z uporabo asyncio:
Mogoče, še vsega ne vem. In sicer zanima me zakaj v korutini "prastevilo", ko awaitam asyncio.sleep() ne preda kontrolo naslednji korutini, ki čaka v event loopu? Zato, ker če zakomentiram to vrstico, večje spremembe v času procesiranja main() funkcije ni. Mogoče sem še kaj pozabil?
async def prastevilo(a): stevila = [] print("Stevilo: " + str(a)) for i in range(1,a+1): if a % i == 0: stevila.append(i) #Ta vrstica naj bi predala kontrolo naslednji funkciji ki caka v event loopu. await asyncio.sleep(0.01) print(len(stevila) == 2) import time import asyncio async def main(): t1 = time.time() await prastevilo(133783472) await prastevilo(125345346) await prastevilo(154654642) t2 = time.time() print("Cas je: " + str(t2-t1)) loop = asyncio.get_event_loop() loop.run_until_complete(main()) loop.close()
Mogoče, še vsega ne vem. In sicer zanima me zakaj v korutini "prastevilo", ko awaitam asyncio.sleep() ne preda kontrolo naslednji korutini, ki čaka v event loopu? Zato, ker če zakomentiram to vrstico, večje spremembe v času procesiranja main() funkcije ni. Mogoče sem še kaj pozabil?
Spura ::
Kaj je logika, po kateri bi ta sleep skrajsal cas izvajanja celega programa. Izracun teh treh prastevil traja enako, ne glede na to ali povsem zaporedno racunas ali ne.
Poleg tega tukaj skoraj povsem zaporedno racunas, sleep je po tem ko si opravil skoraj 100% dela v funkciji, torej je vseeno ce ga ne bi bilo.
Poleg tega tukaj skoraj povsem zaporedno racunas, sleep je po tem ko si opravil skoraj 100% dela v funkciji, torej je vseeno ce ga ne bi bilo.
marjan_h ::
Logika po kateri sem razmišljal je (ne vem če je res), da so v ozadju threadi/procesi. Kar pomeni, da ko začne računati prvo funkcijo praštevilo se paralelno začne izvajati drugo funkcijo praštevilo ipd. Verjetno se tukaj uporablja multithreading ali multiprocessing in Python izkorišča hardware, ki je na voljo npr. večjedrni procesor.
Mogoče lahko, da kdo kakšen primer izračun in uporaba aysincio? Največ je primerov na spletu z requesti. Torej če bi dal await funkcijo ki pošlje zahtevek oddaljenemu strežniku in čaka na odgovor bi delovalo.
Mogoče lahko, da kdo kakšen primer izračun in uporaba aysincio? Največ je primerov na spletu z requesti. Torej če bi dal await funkcijo ki pošlje zahtevek oddaljenemu strežniku in čaka na odgovor bi delovalo.
Mavrik ::
Tvoja logika je ok z izjemo ene malenkosti - "await" je klic, ki počaka na rezultat poklicane async metode. Tako tvoja koda sploh ne teče paralelno, ker ti ukažeš Pythonu da naj počaka na rezultat klica prastevilo() - in to preden mu ukažeš izvajanje naslednje metode.
Če hočeš paralelno izvajanje po tvojem načinu, potem moraš narediti nekaj takega:
ali krajše
Tak vrstni red poskrbi da poženeš vse operacije preden blokiraš s čakanjem na rezultate.
Če hočeš paralelno izvajanje po tvojem načinu, potem moraš narediti nekaj takega:
prastevilo1 = prastevilo(133783472) prastevilo2 = prastevilo(125345346) prastevilo3 = prastevilo(154654642) await prastevilo1 await prastevilo2 await prastevilo3
ali krajše
asyncio.wait(prastevilo1, prastevilo2, prastevilo3)
Tak vrstni red poskrbi da poženeš vse operacije preden blokiraš s čakanjem na rezultate.
The truth is rarely pure and never simple.
Zgodovina sprememb…
- spremenil: Mavrik ()
snuderl ::
Tudi mavrikov odgovor nebo spremenil veliko. Sleep je praktično na koncu metode, tako da se bo kontrola predala šele ko boš že izračunal praštevilo... Če bi recimo želel "simulariti" asinhron potek, bi sleep dal v zanko, in potem dodal še en print. Potem bi lahko videl da se ti izvajanje prepleta.
V nobenem primeru pa se zgornja koda nebo izvajala hitreje saj asinhrono izvajanje kode != paralelno.
V nobenem primeru pa se zgornja koda nebo izvajala hitreje saj asinhrono izvajanje kode != paralelno.
BigWhale ::
V bistvu mors uporabit asyncio.gather(), da hkrati pozenes vse awaitable.
V tvojem primeru bo to blo:
Pa v Python 3.8 imas tudi asyncio.run() in lahko main pozenes kar z: asyncio.run(main()).
V tvojem primeru bo to blo:
await asyncio.gather( prastevilo(133783472), prastevilo(125345346), prastevilo(154654642), )
Pa v Python 3.8 imas tudi asyncio.run() in lahko main pozenes kar z: asyncio.run(main()).
ragezor ::
prastevilo1 = prastevilo(133783472)
prastevilo2 = prastevilo(125345346)
prastevilo3 = prastevilo(154654642)
await prastevilo1
await prastevilo2
await prastevilo3
ne vem, ce se avtomatsko ustvari task in doda v event loop, ko poklices prastevilo(...). mislim, da moras uporabit asyncio.create_task(prastevilo(...)) in to dejansko schedula task. nisem pa ziher.
jype ::
Hkrati je vse skupaj srednja žalost, ker se CPU bound reči v pythonu strahotno slabo skalirajo. Bolje je uporabiti ProcessPoolExecutor iz concurrent futures:
https://docs.python.org/3/library/concu...
https://docs.python.org/3/library/concu...
marjan_h ::
Tudi mavrikov odgovor nebo spremenil veliko. Sleep je praktično na koncu metode, tako da se bo kontrola predala šele ko boš že izračunal praštevilo... Če bi recimo želel "simulariti" asinhron potek, bi sleep dal v zanko, in potem dodal še en print. Potem bi lahko videl da se ti izvajanje prepleta.
V nobenem primeru pa se zgornja koda nebo izvajala hitreje saj asinhrono izvajanje kode != paralelno.
Zelo koristen odgovor. Ja to ni asinhrona koda, hotel sem se spomniti koristen problem, ampak mi to ni uspelo. Ker razni tutoriali na spletu uporabljajo request za primer, procesor čaka, da dobi response od nekega strežnika. Ima kdo še kakšno idejo za asinhrone probleme?
Hvala @BigWhale za await asyncio.gather(), to res požene vse awaitable, vendar ni nič hitreje kot je rekel @snuderl.
galu ::
Za IO (npr. server response wait) je OK.
Tu je kar lepa, čeprav precej abstraktna, primerjava: https://code.luasoftware.com/tutorials/...
Tu je kar lepa, čeprav precej abstraktna, primerjava: https://code.luasoftware.com/tutorials/...
Tako to gre.
BigWhale ::
marjan_h ::
Hvala @BigWhale za await asyncio.gather(), to res požene vse awaitable, vendar ni nič hitreje kot je rekel @snuderl.
A si to stestiral? Ker gather() pozene stvari concurrently, zdaj, ce to spet ni nek pyhton thing, potem bi reci morale teci hitreje.
Ja, sem stestiral. Z gather() dobim 20 sekund, brez pa 16 sekund, kjer ni asinhron potek torej izvaja ukaze enega za drugim. Verjetno je tako kot je opisal @snuderl.
marjan_h ::
Ne vem kdo je Jure, vendar sem pogledal link katerega je prilepil @galu, tam piše za asyncio:
Sem pa mislil, da bo kdo dal real-life primere za asyncio knjižnico npr. če je kdo kaj programiral v službi in je rabil.
Utilize single core only: concurrent but not parallel execution
Sem pa mislil, da bo kdo dal real-life primere za asyncio knjižnico npr. če je kdo kaj programiral v službi in je rabil.
marjan_h ::
Dobro, potem pa Jure, galu in kdorkoli, če lahko napišite realno uporabo asyncio knjižnice, ki se uporablja za concurrency in ne za paralelno kodo. Ni potrebno prilepiti kode, samo primere uporabe. Ker sem kar dost o tem prebral na spletu, ampak so vedno primeri za web requeste.
Hvala.
Hvala.
infiniteLoop ::
Stvar je ponavadi uporabna tam kjer je precej concurrent (kako se temu rece po slovensko?) operacij, katere vecino casa porabijo za cakanje na IO. In posledicno je web streznik, ki streze mnogo zahtevkov naenkrat kar logicen primer. Ni pa to edini primer uporabe. Recimo lahko tudi concurrently izvajas vec klicov podatkovne baze (https://aiopg.readthedocs.io/en/stable/... in se marskiaj drugega. Vec zaokrozenih primerov lahko vidis tudi tule: https://aiohttp-demos.readthedocs.io/en... sicer je vztopna tocka vecinoma HTTP ampak mnogi primeri potem uporabijo asyncio tudi za komunikacijo z drugimi sistemi.
Upam, da ti kaj od tega pride prav. - Srecno
Upam, da ti kaj od tega pride prav. - Srecno
None of us is as dumb as all of us.
jype ::
"CPU bound" pomeni, da procesor počne reči, "I/O bound" pa pomeni, da večino časa čakaš na podatke (z diskov, mreže ali drugod).
Python je zaradi globalnega stanja v interpreterju, ki mora biti zaklenjeno, slab pri prvih in znosen pri drugih rečeh.
Python je zaradi globalnega stanja v interpreterju, ki mora biti zaklenjeno, slab pri prvih in znosen pri drugih rečeh.
Zgodovina sprememb…
- spremenilo: jype ()
Vredno ogleda ...
Tema | Ogledi | Zadnje sporočilo | |
---|---|---|---|
Tema | Ogledi | Zadnje sporočilo | |
» | PythonOddelek: Programiranje | 3049 (1735) | d_DJ |
» | [Raptor] Razcep na prafaktorjeOddelek: Šola | 2453 (1995) | Math Freak |
» | [php] Razbijanje giantskih števil na prafaktorjaOddelek: Programiranje | 2500 (1844) | technolog |
» | Generatorji praštevilOddelek: Znanost in tehnologija | 3850 (2754) | Phil |
» | kako definirtati prasteviloOddelek: Programiranje | 3792 (3597) | ooux |