Kappale 3 - Interrupt

muokkaa

Tehtä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ä
>>>