Simpy - Interrupt
Kappale 3 - Interrupt
muokkaaTehtävä 3
Tee ohjelma, joka leikkii soitinta, joka soittaa musiikki – meidän tapauksessa tulostaa ’Soitan musiikkia’ – lausetta. Satunnaisen ajan kuluttua jokin ulkopuolinen prosessi katkaiseen musiikin soiton 10 sekunniksi, jonka jälkeen musiikin soitto jatkuu, kunnes se taas keskeytyy satunnaisen ajan kuluttua.
Reaalimaailmassa harvat prosessit toimivat ilman satunnaisia, ennalta-arvaamattomia keskeytyksiä. Tällaisia keskeytyksiä meidän tulee kyetä toteuttamaan myös simuloinnissa. Simpy tarjoaa tähän mm. Interrupt – käytännön.
Prosessin – siis ohjelman – keskeyttäminen ihan tosta vaan, aiheuttaisi ohjelman pysähtymisen virhetilanteenseen, joten prosessin mahdollinen keskyttäminen ulkopuolisesta syystä tulee ottaa huomioon ohjelmaa suunnitellessa. Python tarjoaa virhetilanteiden käsittelyyn try-except – rakenteen, jota voimme laajentaa Simpyn Interrupt – menetelmällä. Esimerkki valaisee taas.
Aloitetaan taas tutulla tavalla.
import simpy import random
Sitten itse soita-prosessi, jonne tuomme tuon tutun env-ympäristöparamtrin
def soita(env): print("Soitan....") while True: try: print("Olen soittanut nyt",env.now) yield env.timeout(1) except simpy.Interrupt as voipahus: print("Joku katkaisi musiikin", env.now) print("Jatketaan 10 hetken päästä") yield env.timeout(10)
Mitä tuossa nyt sitten tapahtuu. While True – silmukassa pyöritään ja try:-osiota toteutetaan niin kauan, kuin se onnistuu. Yield env.timeout(1) ’illa saadaan aikaa kulumaan yksi aikayksikkö.
Jos sitten try ei onnistu niin except: – ehto tulee voimaan. Pythonin tavallista except-lausetta on laajennettu simpy.Interrupt as nimi: (nimi valinnassa voi jokainen käyttää omaa harkintaansa). Kun joku ulkopuolinen prosessi keskeyttää soita-prosessin normaalin try-osion toiminnan, ohjelma jatkuu except simpy.Interrupt as – osiosta.
Millainen tämä ulkopuolinen katkaisija prosessi sitten on. Se on tosiaan toinen ohjelmamoduli esim. seuraavanlainen:
def katkaise(env): while True: satunnaisaika = random.randint(10,25) yield env.timeout(satunnaisaika) soitin.interrupt()
Eihän tuo kovin kummoinen ole: ohjelman pätkä, joka on satunnaisen ajan verran tekemättä muuta kuin kuluttamassa aikaa (yield env.timeout) ja sitten käskee soitin.interrupt() .
Mutta hei! Mikäs tämä soitin on? Soittamisestahan huolehtii prosessi nimeltä soita. Tässäpä homman juoni, joka selviää kun lisäämme koodin loppuosan.
env=simpy.Environment() soitin = env.process(soita(env)) env.process(katkaise(env)) env.run(until=50)
Kumpikin soita ja katkaise prosessit käynnistetään omina erillisinä prosesseina (env.process), mutta katkaistava soita-prosessille osoitetaan ulkopuolinen soitin nimi, jota käytetään katkaise-prosessissa ohjaamaan katkaisu oikeaan prosessiin. Näin yksinkertaista tämä on.
Koodi kokonaisuudessaan:
import simpy import random def soita(env): print('Soitan....') while True: try: print('Olen soittanut nyt ',env.now) yield env.timeout(1) except simpy.Interrupt as voipahus: print('Joku katkaisi musiikin', env.now) print('Jatketaan 10 hetken päästä') yield env.timeout(10) def katkaise(env): while True: satunnaisaika = random.randint(10,25) yield env.timeout(satunnaisaika) soitin.interrupt() env=simpy.Environment() soitin = env.process(soita(env)) env.process(katkaise(env)) env.run(until=50)
Ja ajettuna tekee seuraavaa:
Type "copyright", "credits" or "license()" for more information. >>> ========== RESTART: C:/Users/jussi/Documents/Similointi/soitin-2.py ========== Soitan.... Olen soittanut nyt 0 Olen soittanut nyt 1 Olen soittanut nyt 2 Olen soittanut nyt 3 Olen soittanut nyt 4 Olen soittanut nyt 5 Olen soittanut nyt 6 Olen soittanut nyt 7 Olen soittanut nyt 8 Olen soittanut nyt 9 Joku katkaisi musiikin 10 Jatketaan 10 hetken päästä Olen soittanut nyt 20 Olen soittanut nyt 21 Olen soittanut nyt 22 Olen soittanut nyt 23 Olen soittanut nyt 24 Joku katkaisi musiikin 25 Jatketaan 10 hetken päästä Olen soittanut nyt 35 Olen soittanut nyt 36 Olen soittanut nyt 37 Olen soittanut nyt 38 Olen soittanut nyt 39 Olen soittanut nyt 40 Olen soittanut nyt 41 Olen soittanut nyt 42 Joku katkaisi musiikin 43 Jatketaan 10 hetken päästä >>>