Samanaikaisuuden hallinta TIES542 Ohjelmointikielten periaatteet, kevät 2007 Antti-Juhani Kaijanaho Jyväskylän yliopisto Tietotekniikan laitos 20. maaliskuuta 2007
Samanaikaisuus engl. concurrency useampaa ohjelmaa suoritetaan samanaikaisesti ongelmana näiden ohjelmien välinen... kommunikointi resurssienhallinta jaottelu: jaetun muistin samanaikaisuus (shared-memory concurrency) viestinvälityssamanaikaisuus (message-passing concurrency)
Keskeiset ongelmat lukkiutuminen (engl. deadlock) vauhkoontuminen (engl. livelock) nälkiintyminen (engl. resource starvation) toiminnallinen oikeellisuus
viestinvälitys π-laskento (Milner 1992) join-laskento jaettu muisti monitorit transaktiomuisti Tarkasteltavia malleja
π-laskento: abstrakti syntaksi E ::= 0 veltto prosessi I 1 (I 2 ).E vastaanottoetuliite I 1 I 2.E lähetysetuliite E 1 E 2 rinnakkainen yhdistäminen (νi )E rajoitus!e monistus Vastaanottoetuliite x(y).e sitoo muuttujan y ja rajoitus (νx)e sitoo muuttujan x. Muuten esiintyvät muuttujat ovat vapaita.
π-laskento: tulkinta lausekkeet ovat prosesseja muuttujat edustavat kommunikointikanavia viestit ovat myös kommunikointikanavia 0 on prosessi, joka ei tee mitään I 1 (I 2 ).E on prosessi, joka odottaa viestiä kanavalta I 1 ja sitoo viestin muuttujaan I 2 ; sitten se toimii kuten E I 1 I 2.E on prosessi, joka lähettää viestin I 2 kanavalle I 1 (ja odottaa, että joku ottaa sen vastaan); sitten se toimii kuten E (νi )E luo uuden kanavan ja sitoo sen I :hin; sitten se toimii kuten E E 1 E 2 suorittaa prosessit E 1 ja E 2 samanaikaisesti!e luo rajattomasti kopioita prosessista E
π-laskento: rakennekongruenssi E 1 E 2 E 2 E 1 (E 1 E 2 ) E 3 E 1 (E 2 E 3 ) ((νi )E 1 ) E 2 (νi )(E 1 E 2 )!P P!P E 0 E (νi )0 0 jos I ei vapaa E 2 :ssa
π-laskento: operationaalinen semantiikka I 1I 2.E 1 I 1(I 3).E 2 E 1 E 2[I 3 := I 2] E 1 E 1 E 1 E 2 E 1 E 2 E E (νi )E (νi )E E 1 E 1 E 1 E 2 E 2 E 2 E 1 E 2
Esimerkkejä 1. Voidaan määritellä usean viestin yhtäaikainen lähettäminen ja vastaanottaminen: I I 1,..., I n.e = (νi )I I.I I 1..I I n.e I (I 1,..., I n ).E = I (I ).I (I 1 )..I (I n ).E 2. Voidaan myös määritellä totuusarvot: True(b) =!b(t, f ).t False(b) =!b(t, f ).f Tällöin jos halutaan prosessin E 1 tulevan suoritettua, jos kanava b on tosi (eli rinnalla suoritetaan prosessia True(b)) ja E 2 :n tulevan suoritettua, jos kanava b on epätosi, niin tämä saadaan aikaan prosessilla (νt)(νf )b t, f.(t().e 1 f ().E 2 )
Esimerkki Voidaan määritellä myös muistikas : Ref(r, w, i) = (νl)l i ReadServer(l, r) WriteServer(l, w) ReadServer(l, r) =!r(c).l(v).(c v l v ) WriteServer(l, w) =!w(c, v ).l(v).(c l v ) Prosessi Ref(r, w, i) luo muistikkaan, jonka alkuarvo on l. Muistikkaan nykyinen arvo on luettavissa lähettämällä jokin viesti c kanavalle r; arvon voi lukea kanavalta c. Muistikkaan arvon voi vaihtaa arvoksi v lähettämällä pari c, v viestinä kanavalle w; kun kanavalle c tulee tyhjä viesti, on muistikkaan arvo päivittynyt.
Esimerkki Voidaan määritellä kuvaus puhtaan tyypittömän λ-lausekkeen lausekkeilta π-laskennon lausekkeiksi. Kuvaus ottaa parametrina myös kanavanimen. λx.e (p) = p(x, q). E (q) x (p) = x p E 1 E 2 (p) = (νq) E 1 (q) ((νy)q y, p!y(r). E 2 (r))
π-laskennon merkitys suosittu formalismi viestinvälityksen semantiikan tutkimiseen voidaan käyttää samanaikaisuutta tukevan viestinvälityspohjaisen ohjelmointikielen perustana (kuten λ-laskento on funktiokielen perusta) esim. Pict ei kuitenkaan ainoa mahdollinen viestinvälityksen teoria
Join-laskento Fournet ja Gonthier 1996 π-laskennossa viestinvälitys on synkronoivaa erityisesti synkronointi on globaali tapahtuma hankalaa hajautetussa järjestelmässä Join-laskento synkronoi lokaalisti tarkemmin taululla Polyphonic C#, C ω
Monitorit Per Brinch Hansen 1972 rakenteinen lukitus jaetun muistin järjestelmässä olennaisesti: monitori on Java-luokka, jonka jokainen metodi on synchronized ja jokainen attribuutti on private Per Brinch Hansen: Java s Insecure Parallelism. SIGPLAN Notices 34(4): 38-45 (1999)
Muistitransaktiot Software Transactional Memory (STM) atomic {... } joko koko atomic-lause suoritetaan kokonaan tai sitä ei suoriteta lainkaan optimistinen strategia: oletetaan, että kaikki käy hyvin, ja atomic-lauseen lopussa katsotaan, onnistuiko onnistui, jos mikään muu säie ei atomicin aikana kirjoittanut muuttujiin, joita tämä säie luki atomicin sisällä; tällöin kaikki on hyvin (commit) jos epäonnistui, perutaan tehdyt muutokset muuttujien arvoihin ja aloitetaan atomic-lohko alusta (rollback-retry) retry jos retry suoritetaan, pakotetaan nykyisen atomicin rollback-retry {... } orelse orelse {... } jos lohko tekee rollbackin, älä jää odottamaan vaan kokeile seuraavaa lohkoa