keskiviikko 11. maaliskuuta 2009

Luento 16 - Yhteismuistisamanaikaisuus

Luennon aluksi eroteltiin samanaikaisuuden (concurrent) ja rinnakkaisuuden (parallel) käsitteet. Rinnakkaisesti etenevät tapahtumat ovat toisistaan riippumattomia. Samanaikaisuuden tapauksessa näin ei ole.

Tätä eroa voi kenties havainnollistaa pienellä esimerkillä. Olkoon Aaro ja Eero, jotka rakentavat kumpikin omaa majaansa. Kuopan kaivaminen on rinnakkaista, jos kummallakin on omat työvälineensä ja he rakentavat majaansa omassa paikassaan. Mikäli he joutuvat jakamaan työvälineitään edes jossain määrin, muuttuu tapahtuma käsittääkseni samanaikaiseksi juuri tämän riippuvuuden vuoksi. Voi olla, että Eero joutuu lainaamaan Aaron kirvestä, joka on hänellä käytössä. Tässä tapauksessa lienee luontevaa odottaa, ellei jotain muuta järkevää ole tehtävissä.

Olen taipuvainen näkemään rinnakkaisuuden käsitteen alisteisena samanaikaisuuden käsitteelle. Tuntuu järkevältä, että samanaikaisessa tapahtumassa osia voidaan suorittaa rinnakkain. Samanaikaisuus asettaa tosin yllä esitetyn esimerkin tapaisia rajoitteita, joita puhtaassa rinnakkaisuudessa ei ole.

Luennolla samanaikaisuus jaettiin kahteen ohjelmointikielten näkökulmasta kahteen lohkoon: yhteismuisti- ja viestinvälityssamanaikaisuuteen. Näistä ensimmäinen oli tämän luennon aiheena. Jälkimmäistä käsiteltiin seuraavalla luennolla. On huomattava, että molemmat tavat ovat yleisesti käytössä.

Mistä yhteismuistisamanaikaisuudessa on kysymys? Tässä tapauksessa samanaikaisesti suoritettavat tapahtumat jakavat osan yhteistä muistia, johon kumpikin pääsee käsiksi. Esimerkiksi yllä yhteismuistiin voitaisiin tallentaa Aaron ja Eeron käytettävissä olevat työkalut ja niiden tila (onko käytössä, kuka käyttää).

Yhteismuistin tapauksessa ongelmaksi muodostuu, kuinka hallita tätä yhteistä muistia. Toisaalta kunkin samanaikaisesti suoritettavan tapahtuman tulisi olla synkronoitu keskenään siten, että ne eivät voi olla keskenään virheellisessä tilassa. Toisin sanoen, jos Aarolla ja Eerolla on käytössään vain yksi kirves, ei heidän kummankin tulisi olla mahdollista käyttää samaa kirvestä eri paikoissa samanaikaisesti.

Eräs varsin käytetty ratkaisu on lukkojen käyttö. Tässä tapauksessa haluttu resurssi lukitaan siten, että sitä voi käyttää vain yksi käyttäjä kerrallaan. Toisaalta lukkojen suhteen lienee mahdollista tehdä eri kokoisia rajauksia. Voisikin kuvitella, että ääritapauksessa koko yhteismuistialueen voisi lukita. Tässä mielessä lukot muistuttavatkin tietokantoja ja niiden synkronointia. Pohjimmiltaan kyse onkin samasta ongelmasta.

Mitä yllä mainittu tarkoittaa ohjelmointikielten kannalta? Ohjelmointikieli voi ottaa selvästi kantaa samanaikaisuuteen tai se voi jättää samanaikaisuuden hallinnan kirjastojen vastuulle. Näkisin kirjastototeutuksen (esim. C ja POSIX) joustavampana. Toisaalta luennolla mainittiin, että kielissä, joissa samanaikaisuus on jätetty vähemmälle huomiolle, ei kirjastojen toteuttaminen ole välttämättä aivan yksioikoista. Kielen tulisikin olla määritelty tietyllä tavalla, jotta kirjastoja voisi toteuttaa täsmällisellä tavalla.

Luennolla mainittiin myös kriittisten lohkojen käsitteestä. Kriittiset lohkot suoritetaan siten, että kaikki muut tehtävät on pysäytetty. Lisäksi niiden sisällä olevaa toiminnallisuutta on rajoitettu. Tästä esitettiin myös kehittyneempi ehdollinen versio.

Aaron ja Eeron tapauksessa tämä lienee tarkoittaisi siteä, että lohkon avulla voisi samanaikaisuutta rajoittaa tapahtumien tasolla. Voisi esimerkiksi asettaa rajoitteen, jonka mukaan vain yksi henkilö kerrallaan saa maalata seiniä. Toisaalta tämänkin tulisi olla mahdollista vain, jos maalia on jäljellä ja ulkona on vielä valoisaa.

Luennon loppupuolella esitettiin abstraktimpi ratkaisu, monitori. Monitori kapseloi jaetut muuttujat operaatioiden avulla. Toisaalta vain yksi tehtävä voi käyttää operaatioita kerrallaan. Muut tehtävät asetetaan jonotuslistaan, kuten pankissa ikään. Tämän lisäksi monitori sisältää ehdollisia jonoja. Ehdollinen jono voitaisiin kenties toteuttaa siten, että ehdollisessa jonossa oleva tehtävä siirretään oikean jonotuslistan eteen ehdon toteutuessa. Tässä tapauksessa se suoritettaisiin heti monitorin suorituksen vapauduttua (olettaen, että suoritettavat tehtävät poimitaan jonosta järjestyksessä).

Aivan lopuksi esitettiin transaktion käsite. Transaktioiden käsite on lainattu suoraan tietokantojen puolelta. Oleellisesti transaktio olettaa, että jo toteutettu tapahtuma voidaan perua. Tämä asettaa joitain rajoitteita sille, mitä voidaan tehdä, mutta toiminee mukavasti, kunhan peruminen on mahdollista. Toisaalta on selvää, ettei kaikkea voi perua. Tässä tapauksessa joutunee käyttämään jotain muuta tekniikkaa. Voisi ajatella esimerkiksi käyttävänsä transaktioiden lisäksi ehdollisia kriittisiä lohkoja tai jotain muuta täydentävää tapaa.

1 kommentti: