Upload
others
View
1
Download
0
Embed Size (px)
Citation preview
Lappeenrannan teknillinen yliopisto
Teknistaloudellinen tiedekunta
Tietotekniikan koulutusohjelma
Käyttöjärjestelmät
Seminaarityö
Joonas Asikainen, Joel Kurola, Sampo Lankinen
Poissulkeminen, nälkiintyminen ja lukkiutuminen
ii
TIIVISTELMÄ
Lappeenrannan teknillinen yliopisto
Teknistaloudellinen tiedekunta
Tietotekniikan koulutusohjelma
Joonas Asikainen, Joel Kurola, Sampo Lankinen
Poissulkeminen, nälkiintyminen ja lukkiutuminen
Seminaarityö
2009
24 sivua, 2 kuvaa, 0 taulukkoa ja 0 liitettä
Hakusanat: poissulkeminen, nälkiintyminen, lukkiutuminenKeywords: mutual exclusion, starvation, deadlock
Seminaarityössämme käsittelemme pyrkimystä estää poissulkemisen uhkaa toteutumasta käyttöjär-
jestelmien toiminnassa ja menetelmiä prosessien lukkiutumisen tai nälkiintymisen estämiseksi nii-
den kilpaillessa järjestelmän resursseista. Lisäksi käymme läpi sitä, kuinka tilanne voidaan purkaa,
jos tällainen tilanne on jo päässyt muodostumaan.
Mikään näihin kolmeen ongelmaan liittyvistä ja tähän mennessä löydetyistä menetelmistä ei ole
täydellinen ratkaisu ongelmiin, vaan jokaisella on omat hyötynsä ja haittansa. Uusia algoritmeja
resurssien jakoon, tilanteiden ennakointiin ja jo syntyneiden ongelmatilanteiden purkamiseksi kehi-
tetään jatkuvasti sekä käyttöjärjestelmä- että sovelluskehittäjien toimesta.
iii
ABSTRACT
Lappeenranta University of Technology
Faculty of Technology Management
Degree Program of Information Technology
Joonas Asikainen, Joel Kurola, Sampo Lankinen
Mutual exclusion, starvation and deadlock
Seminar work
2009
24 pages, 2 figures, 0 tables and 0 appendices
Keywords: mutual exclusion, starvation, deadlock
In our seminar work we will discuss the effort to prevent the threat of mutual exclusion from hap-
pening in the operation of operating systems and methods for preventing deadlocking and starvation
of processes when they are contending for the resources of the system. Additionally we will also
handle how the situation can be unravelled, if a situation of such has already been build up.
Not one of the methods found until now and associated with these three problems is a perfect solu-
tion for the problems, but they all have their advantages and disadvantages. New algorithms for the
distribution of resources, prediction of conditions and for fixing problem situations that have al-
ready been build up are constantly been developed by both operating system- and application de-
velopers.
iv
ALKUSANAT
Seminaarityömme on tehty kurssille CT20A2601 - Käyttöjärjestelmät. Työn aihetta valitessamme
meillä ei ollut ennestään kovinkaan tarkkaa kuvaa työn aiheesta, mutta saatuamme nyt työn kunnial-
la päätökseen olemme oppineet paljon ja saaneet runsain määrin hyödyllistä tietoa.
Aiheeseen liittyvien tieteellisten julkaisujen löytäminen osoittautua hieman hankalaksi ja siksi luo-
tettavien internet-lähteiden käyttö muodostui tärkeäksi työtä koostettaessa. Olemme hyvin tyytyväi-
siä työmme tulokseen ja kiitämme läheisiä kärsivällisyydestä.
Lappeenrannassa 2. toukokuuta 2009
1
SISÄLLYSLUETTELO
1. Johdanto.................................................................................................................................. 3
2. Poissulkeminen ....................................................................................................................... 4
2.1 Keskeytysten estäminen .................................................................................................... 4
2.2 Semaforit eli opastimet ..................................................................................................... 5
2.3 Monitorit........................................................................................................................... 6
2.4 Viestin välitys ................................................................................................................... 7
2.5 Dekkerin algoritmi ............................................................................................................ 8
3. Lukkiutuminen ........................................................................................................................ 9
3.1 Lukkiutumisen ehdot....................................................................................................... 10
3.2 Lukkiutumisen havaitseminen, ehkäiseminen ja välttäminen........................................... 10
3.3 Aterioivien filosofien ongelma ........................................................................................ 12
3.3.1 Ratkaisumalli: Tarjoilija........................................................................................... 14
3.3.2 Ratkaisumalli: Hierarkkiset resurssit ........................................................................ 14
3.4 Pankkiirin algoritmi ........................................................................................................ 14
3.5 Lukkiutumisesta palautuminen........................................................................................ 15
4. Nälkiintyminen...................................................................................................................... 17
5. Yhteenveto ............................................................................................................................ 18
Lähteet.......................................................................................................................................... 19
2
SYMBOLI- JA LYHENNELUETTELO
IPC Inter-process communication
I/O Input/output siirräntä
3
1. Johdanto
Nykyaikaisissa usean käyttäjän käyttöjärjestelmissä pyritään tasapuolisesti jakamaan käy-
tettävissä olevat resurssit – prosessoriaika, vapaa muisti, tallennustila massamuistissa sekä
i/o-yhteydet tiedostojärjestelmään ja muihin järjestelmän laitteisiin. Kun käyttäjille pyri-
tään takaamaan mahdollisimman interaktiivinen ja nopeasti toimintoihin vastaava käyttö-
liittymä, joutuu käyttöjärjestelmä usein pätkimään prosessien, tai säikeiden, suoritusta pie-
nehköihin aikaviipaleisiin.
Koska käyttöjärjestelmä ei pysty juurikaan ennakoimaan, milloin olisi prosessin kannalta
hyvä aika keskeyttää sen toiminta, joutuu se turvautumaan erilaisiin algoritmeihin, joiden
perusteella se jakaa prosessointiaikaa eri prosessien kesken. Tällöin itse prosessi ei pysty
varmuudella tietämään, milloin jokin toinen prosessi saa prosessorin itselleen ja se joutuu
itse odottamaan ajoon pääsyä. Tämä aiheuttaa tilanteita, joissa prosessin suoritus katkais-
taan prosessin toiminnan kannalta kriittisellä hetkellä, ja jokin toiminto jää kesken. Jos nyt
jokin toinen prosessi tarvitsee samaa resurssia, jonka käsittely aiemmalta prosessilta jäi
kesken, on vaarana, että dataa korruptoituu ja yhden tai useamman prosessin toiminta häi-
riintyy pahasti, koska resurssin tila on olennaisesti muuttunut prosessin odottaessa vuoro-
aan päästä takaisin ajoon ja suorittamaan keskeytynyt toiminto loppuun.
Pyrkimyksestä estää muita prosesseja korruptoimasta prosessin tarvitsemaa resurssia kriit-
tisellä hetkellä syntyy poissulkemisen ongelma. Kuinka estää toisten prosessien pääsy re-
surssiin tehokkaasti silti häiritsemättä niiden toimintaa? Kuinka välttää resurssien turhaa
varaamista ilman, että teet oman toimintasi tehottomaksi? Kuinka estää prosesseja lukkiu-
tumasta tai nälkiintymästä niiden kilpaillessa järjestelmän resursseista tai purkaa tilanne,
jos näin on jo päässyt käymään?
Näihin kysymyksiin pyritään löytämään vastauksia ja tarjoamaan vaihtoehtoja seuraavien
kappaleiden aikana. Tällä hetkellä mikään tunnettu menetelmä ei ole täydellinen vaan jo-
kaisella on omat hyötynsä ja haittansa. Algoritmeja resurssien jakoon, tilanteiden enna-
kointiin ja jo syntyneiden ongelmatilanteiden purkamiseen kehitetään jatkuvasti sekä käyt-
töjärjestelmä- että sovelluskehittäjien toimesta.
4
2. Poissulkeminen
Paras tapa välttää tarve poissulkemiselle, englanniksi mutual exclusion tai lyhyemmin mu-
tex, ja siten siitä mahdollisesti aiheutuville muille ongelmille, on käyttää vain sellaisia re-
sursseja, joita voidaan käyttää yhtä aikaa ilman, että siitä aiheutuu haittaa yhdellekään re-
surssia käyttävälle prosessille. Valitettavasti useat resurssit ovat kuitenkin sellaisia, että ne
täytyy varata yksinomaan yhden prosessin käyttöön ainakin lyhyeksi aikaa, jotta haluttu
toiminto pystytään suorittamaan. Esimerkiksi tulostinta pystyy käyttämään vain yksi pro-
sessi kerrallaan, jotta saadaan tulostettua dokumentit sellaisina kuin oli tarkoitus, ja tiedos-
toa tai tietokannan tiettyä alkiota pystyy päivittämään vain yksi prosessi kerrallaan, ettei
kirjoitettava data korruptoidu. Datan päivityksen aikana on luonnollisesti myös estettävä
datan lukeminen, jottei lukeva prosessi lukisi osittain vanhaa ja osittain uutta dataa. Poik-
keuksen tekevät sellaiset resurssit joiden luku- ja kirjoitusalueet ovat aina erillään toisis-
taan tai joita käsitellään ohjelman ulkopuolisten luku- ja kirjoitusrutiinien avulla, esimer-
kiksi putket (pipe) tai puskurit (buffer). [1]
Kun tulee tarve saada yksinoikeus jonkin resurssin käyttöön, tarvitaan jokin keino estää
muita prosesseja käyttämästä resurssia. Samalla tulisi kuitenkin pitää huoli myös siitä, ettei
resurssien varaaminen aiheuta usean prosessin lukkiutumista (deadlock) tai yhden tai use-
amman prosessin nälkiintymistä (starvation). Ongelman ratkaisuun voidaan käyttää kes-
keytysten estämistä, semaforeja eli opastimia, monitoreja ja viestien välitystä. [1]
2.1 Keskeytysten estäminen
Poissulkemisongelma voi syntyä siinä kohtaa, missä laiteajurien keskeytyskäsittelijät käsit-
televät samoja tietorakenteita kuin i/o-palvelurutiinit (read, write, … ). [2] Ongelma pysty-
tään ratkaisemaan estämällä keskeytykset siksi aikaa, että haluttu toimenpide saadaan suo-
ritettua. Keskeytysten estäminen on tehokas toimenpide, mutta sitä ei pitäisi käyttää kuin
hyvin lyhyitä aikoja kerrallaan. Lisäksi sitä ei voi käyttää, jos prosessin tarvitsee odottaa
jotain tapahtumaa kriittisellä alueella. Keskeytysten estämisen käyttökelpoisuus on kuiten-
kin jäämässä minimaaliseksi, koska se ei toimi moniprosessorijärjestelmissä, jotka yleisty-
vät kovaa vauhtia. [3]
5
2.2 Semaforit eli opastimet
Semafori on laskuri, joka kertoo kuinka monta käyttölupaa tai yksikköä siihen liittyvään
resurssiin on käytettävissä. Sillä pystytään esimerkiksi tasaamaan tietokantaan kohdistuvaa
kuormaa sallimalla vain rajattu määrä prosesseja kommunikoimaan tietokannan kanssa
kerralla, tai jakamaan prosessin varaamia puskureita sen säikeille enintään rajatun maksi-
mimäärän verran kerrallaan. Semafori voi olla myös binäärinen, eli joko resurssin käyttöön
on lupa tai sitä ei ole (se on jo jonkin prosessin käytössä). Lisäksi semaforiin voi liittyä
odotusjono, johon resurssia pyytävät prosessit laitetaan odottamaan vapautuvaa resurssia.
Resurssien jako jonossa odottaville prosesseille voi tapahtua joko pyytämisjärjestyksessä
tai jonkin prioriteetin mukaan. Yleisimmin semaforeja käytetään binäärisinä prosessien
(säikeiden) yhteisten resurssien kontrollointiin sallien vain yhden prosessin kerrallaan
käyttää resurssia, esimerkiksi jaettua muistialuetta, tiedostoa tai ulkoista laitetta. [4]
Binäärisellä semaforilla S on kaksi operaatiota: wait(s) ja signal(s). Wait–operaatio pyytää
semaforilta lupaa käyttää resurssia, joka sille myönnetään, jos resurssi ei ole käytössä.
Muutoin prosessi lisätään semaforin S odotusjonoon. Kun prosessi on suorittanut toimin-
tonsa, suorittaa se signal–operaation, jolloin semafori valitsee odotusjonosta seuraavan
prosessin jolle lupa resurssin käyttöön annetaan. Laskurisemaforeilta voidaan usein pyytää
kerralla lupa useamman resurssin käyttöön. Tällöin operaatioiden parametreihin lisätään
pyydettyjen lupien määrä (wait(s, k), signal(s, k)). [4]
Semaforien toiminnan kannalta on oleellista, että wait ja signal ovat jakamattomia eli ato-
misia operaatioita. Tällä tarkoitetaan sitä, että vain yksi prosessi kerrallaan voi olla suorit-
tamassa operaatiota tietylle semaforille. Voidaan siis ajatella, että nämä operaatiot ovat
yksittäisen konekäskyn asemassa. Semaforien käyttö vaatii yleensä rautatason tukea, jotta
tarvittavat operaatiot pystytään suorittamaan ilman keskeytyksen mahdollisuutta. [5]
Usean semaforin käyttö monen prosessin (säikeen) kokonaisuudessa voi antaa mahdolli-
suuden lukkiutumiselle, jos prosessit pyytävät kerralla lupaa useammalta semaforilta tai
voivat semaforin odotuksen aikana joutua pysyvästi blocked-tilaan jostain muusta syystä.
Myös sisäkkäisten semaforien käyttöä tulisi välttää lukkiutumistilanteiden estämiseksi. [4]
Poissulkemisongelman ratkaisu semaforien avulla voi aiheuttaa ongelmia kokonaisjärjes-
telmän reaaliaikaisuuden suhteen varsinkin, jos käyttöjärjestelmä valitsee ajettavat proses-
6
sit kiinteän prioriteetin perusteella. On esimerkiksi mahdollista, että matalan prioriteetin
prosessi keskeytetään kriittisellä alueella, jolloin prosessilla on yksinoikeus johonkin re-
surssiin, ja suoritusvuoroon valitaan korkean prioriteetin prosessi, joka haluaisi käyttää
samaa resurssia, muttei pysty ohittamaan matalan prioriteetin prosessia tämän hallussa
olevan semaforin takia. Tätä kutsutaan käänteisprioriteettiongelmaksi (priority inversion).
[6]
2.3 Monitorit
Monitori on semaforia kehittyneempi yhteisen tiedon valvoja. Se koostuu yhteisestä tiedos-
ta ja sitä käsittelevistä operaatioista, jotka se kapseloi sisäänsä niin, että niitä pääsee suorit-
tamaan enintään yksi prosessi (säie) kerrallaan vain monitorin suostumuksella. Monitori
siis kapseloi sisäänsä poissulkemisen, jolloin yksittäisen prosessin ei tarvitse siitä huoleh-
tia. Monitorin sanotaan olevan käytössä, kun jokin prosessi käyttää jotain sen operaatiota.
[2]
Toteutuksesta riippuen monitori voi sisältää yhden yhteisen jonon kaikille sen käyttöä ha-
luaville prosesseille, tai useita jonoja joihin on liitetty ehtoja. Ehdollisten jonojen ajatus on
tarjota prosesseille paikka odottaa jonkin tietyn ehdon toteutumista ennen kuin sille anne-
taan monitori käyttöönsä. Tästä on hyötyä silloin, kun prosessi voi suorittaa monitorin val-
voman operaation vain tietyn ehdon voimassa ollessa. Yleensä ehdot liittyvät monitorin
valvomaan tietoon. Esimerkiksi monitorin valvoessa pankkitilin saldon muuttamista, voi-
daan lasku maksaa velkojalle vain silloin kun tilin saldo on vähintään laskun loppusumman
suuruinen. Tällöin monitori voi asettaa laskunmaksurutiinin odottamaan saldon kasvamista
tarvittavan suuruiseksi ja ehdon toteuduttua antaa rutiinin suorittaa laskun maksaminen.
Monitori vapautuu, kun sitä käyttävä prosessi on saanut suoritettua haluamansa operaation
loppuun. Tällöin monitori valitsee seuraavan prosessin, joka saa monitorin käyttöönsä.
Toteutustavasta riippuen prioriteetin voi saada mikä tahansa jonottava prosessi, joka on
valmis suoritettavaksi. Usein etusijan saa ehdollista suoritusta odottava prosessi, jonka ehto
on toteutunut. Jos yhtään suorituskelpoista kandidaattia ei löydy, vapauttaa monitori itsen-
sä uusien prosessien käytettäväksi.
Monitorit sisältävät usein semaforeja, jotka käytännössä toteuttavat poiskulkemisen. Moni-
torien keskeisenä tavoitteena on rajoittaa virhemahdollisuuksia. Monitorin avulla yhteisen
7
tiedon käyttäjien ei itse tarvitse huolehtia toistensa poissulkemisesta, sillä kaikki yhteisen
tiedon käsittely tapahtuu valvojan, monitorin, alaisuudessa. [2]
Monitorit tulisi suunnitella mahdollisimman yksinkertaisiksi ja niiden suorittamien operaa-
tioiden tulisi olla mahdollisimman nopeita ja koskea ainoastaan kriittistä dataa tai laitetta,
jonka käyttöä monitori valvoo. Monitorin operaatioiden ei myöskään tulisi käyttää toisia
monitoreja, semaforeja tai muita toimintoja, jotka voivat aiheuttaa monitorin joutumisen
blocked-tilaan. [2]
2.4 Viestin välitys
Yhteisten muuttujien (semaforien ja monitorien) käyttö perustuu siihen, että prosesseilla on
jokin yhteinen muistialue. Jos järjestelmä on hajautettu, pitää kommunikoinnissa turvautua
viestien välitykseen. Viestien käyttö saattaa olla perusteltua, vaikka yhteistä muistia olisi-
kin. Viesti on yleensä lyhyt (yksi muistisana) ja usein osoitin suurempaan tieto-objektiin.
Viestin välityksen kannalta keskeinen termi on IPC, inter-process communication, joka
tarkoittaa kahden prosessin, tai säikeen, välistä informaation vaihtoa. [5]
Kommunikoivia prosesseja (säikeitä) voidaan suorittaa samassa prosessorissa, moniproses-
sorisen tietokoneen missä tahansa prosessorissa tai jopa kokonaan toisessa tietokoneessa.
Viimeisimmässä tapauksessa viestintä rajoittuu tietoverkon, tai muun datalinkin, kautta
tapahtuvaan tiedonsiirtoon. [4]
Tiedonsiirrossa eri prosessien välillä on yksinkertaisimmillaan kaksi kutsua: lähetys ja vas-
taanotto. Viestien välittämiselle prosessista toiseen on olemassa kaksi eri mallia: synkroni-
nen ja asynkroninen viestinvälitys. Synkroninen viestinvälitys tarkoittaa sitä, että vastaan-
ottaja odottaa koko viestin saapumista ja jatkaa suoritusta vasta tämän jälkeen. Asynkroni-
sessa viestinvälityksessä riittää, kun vastaanottaja saa tiedon, että viesti on tulossa ja voi
jatkaa toimintaa heti tämän tiedon saamisen jälkeen. Vastaavat säännöt koskevat myös
viestin lähetysprosessia. [7]
Viestinvälitystä voidaan käyttää yhteisten resurssien käyttövuorojen jakoon. Jokin prosessi
voi huolehtia vuorojen jakamisesta tai prosessit voivat keskenään sopia kuka milloinkin
käyttää resurssia. Prosessien sijaitessa samassa järjestelmässä voi resurssi olla mikä tapan-
sa laitteesta löytyvä resurssi jota ei pystytä jakamaan kaikkien kesken samanaikaisesti. [4]
8
Tällainen resurssi voi olla vaikkapa tiedosto, jota prosessit päivittävät tai putki johon pro-
sessit kirjoittavat tai josta ne lukevat. Prosessien sijaitessa eri järjestelmissä, sijaitsee jaet-
tava resurssikin yleensä jossain järjestelmien ulkopuolella, esimerkiksi internetissä tai sisä-
verkossa. Tällöin resurssi voisi olla esimerkiksi päivitettävä tiedosto, yksinkertainen tieto-
kanta tai jokin laite jolta prosessit vuorollaan lukevat syötettä tai jolle ne lähettävät dataa.
[4]
Yleensä verkossa sijaitsevat resurssit sijoitetaan jonkin rajapinnan taakse, joka hoitaa pois-
sulkemisongelman itsenäisesti. Tällöin prosessien ei tarvitse keskustella keskenään ja vuo-
rottaa toimintaansa, joten niistä saadaan yksinkertaisempia. Toki prosessi saattaa edelleen
joutua odottamaan vuoroaan saadakseen tarvitsemansa toiminnon suoritettua. [4]
Myös viestinvälityksessä on vaara joutua lukkiutumistilaan. Resurssin omaava prosessi voi
esimerkiksi kuolla, jolloin resurssi jää vapauttamatta ja muut prosessit jäävät odottamaan.
Viesti voi myös kadota matkalla, mikä ei internetissä ole edes kovin harvinaista, ja jos
viestien perille menoa ei varmisteta, voi olla tuloksena prosesseja jotka odottavat resurssia
ilman, että kukaan tietää niiden sitä tarvitsevan. Lukkiutumista tarkastellaan tarkemmin
työn 3. luvussa. [4]
2.5 Dekkerin algoritmi
Dekkerin algoritmi on hollantilaisen matemaatikon T. J. Dekkerin poissulkemiseen luoma
rinnakkaisohjelmoinnin algoritmi, joka antaa kahden kuidun jakaa yksittäiseen käyttöön
tarkoitettu resurssi ilman konfliktia, käyttäen kommunikointiin ainoastaan jaettua muistia.
Algoritmi välttää vuorottelualgoritmin tiukan vuorottelun ja oli yksi ensimmäisiä poissul-
kemiseen keksittyjä algoritmeja. Yksi algoritmin eduista on, että se ei tarvitse erityisiä
read/modify/write-ohjeita, joten se on helposti siirrettävissä kielestä tai konearkkitehtuuris-
ta toiseen. Sitä vastoin se on rajoitettu vain kahteen prosessiin ja käyttää odottamista kes-
keyttämisen sijaan. Toinen vastaava algoritmi on Gary Petersonin algoritmi, jota on mah-
dollista soveltaa useammallekin prosessille, vaikka se alun perin toimikin vain kahdella.
[2]
9
3. Lukkiutuminen
Prosessien välinen kilpailu rajallisista resursseista saattaa jossain tapauksissa johtaa tilan-
teeseen, missä mikään prosessi ei pysty jatkamaan suoritustaan. Tilannetta, jossa kaksi tai
useampi prosessi (säie) odottaa toistensa vapauttavan jonkin resurssin tai muuttavan jonkin
resurssin tilaa pystyäkseen jatkamaan suoritustaan kutsutaan nimellä deadlock. Tällöin
mikään joukkoon kuuluva prosessi ei pysty jatkamaan suoritustaan eikä tilannetta pystytä
purkamaan ilman ulkopuolista väliintuloa tai erityistä mekanismia, jolla prosessit itse ha-
vaitsevat lukkiutumisen. [8, 9]
Ohjelmallisesti lukkiutumisen havaitseminen on erittäin hankalaa ja yleensä lukkiutumisen
purkumekanismi vain olettaa mahdollisen lukkiutumisen tapahtuneen, kun se ei tiettyyn
aikaan ole haluamaansa resurssia saanut. Tällöin prosessi voi perua pyyntönsä, ja vapauttaa
mahdollisesti jo varaamansa resurssit, ja hetken odotuksen jälkeen yrittää varata uudelleen
tarvitsemiaan resursseja toivoen, että lukkiutuminen olisi purkaantunut odotuksen aikana.
Toimenpiteellä ei kuitenkaan välttämättä ole kokonaistilanteen kannalta mitään hyötyä, jos
muut prosessit eivät omaa vastaavaa mekanismia tai jos mekanismien toteutus ei anna
muille prosesseille tarpeeksi aikaa ajaa omat mekanisminsa ja siten saada jokin prosessi
ajoon ennen kuin resurssit ovat taas varattu ja lukkiutuminen aikaansaatu uudelleen. Liian
herkästi reagoiva lukkiutumisenpurkumekanismi voi myös johtaa prosessin nälkiintymi-
seen sen antaessa toisten viedä resurssinsa aika ajoin vaikka todellista lukkiutumista ei ole
tapahtunut. [8, 9]
Tilannetta, jossa tapahtuu toimintoja, mutta ei minkäänlaista edistystä, nimitetään puoles-
taan termillä livelock. Tällainen tapaus on esimerkiksi aktiivinen odotus, eli niin kutsuttu
spinlock tai busy loop (busy wait), jossa prosessi ikuista silmukkaa suorittaen yrittää saada
käyttöönsä tarvitsemansa resurssin (sitä koskaan saamatta). Monet käyttöjärjestelmät käyt-
tävät niin sanottua adaptiivista mutexia, joka ensin pyrkii saamaan tarvitsemansa resurssin
spinlockin avulla, mutta tietyn ajan tai yritysmäärän jälkeen pysäyttää silmukan ja siirtää
prosessin taustalle (sleep) odottamaan resurssin vapautumista. Kyseinen lähestymistapa on
prosessori- ja käyttäjäystävällisempi, koska prosessorin ei tarvitse aika ajoin suorittaa
ikuista silmukkaa tarpeettomasti, mutta sillä ei ratkaista lukkiutumisen ongelmaa. [9]
10
3.1 Lukkiutumisen ehdot
Lukkiutumisen tapahtuminen on mahdollista ainoastaan kun neljä ehtoa on voimassa. Nä-
mä ehdot ovat: [10]
− poissulkemisehto (mutual exclusion)
− varaus–odotusehto (hold and wait)
− irrottamattomuusehto (no preemption)
− silmukkaodotusehto (circular wait)
Poissulkemisehto tarkoittaa, että prosessin varaama resurssi ei ole muiden prosessien käy-
tössä ennen kuin se on vapautettu. Varaus–odotusehto tarkoittaa sitä, että prosessi varaa
saamansa resurssit lisäksi tarvitsemiensa resurssien odotuksen ajaksi. Irrottamattomuusehto
tarkoittaa puolestaan sitä, että vain prosessi itse pystyy vapauttamaan varaamansa resurs-
sin. Silmukkaodotusehto tarkoittaa sitä, että on olemassa joukko prosesseja (säikeitä), jotka
kaikki odottavat jotain toisen joukkoon kuuluvan prosessin varaamaa resurssia. Jos yksikin
ehto ei ole voimassa, ei voi tapahtua lukkiutumista. [10, 11]
3.2 Lukkiutumisen havaitseminen, ehkäiseminen ja välttäminen
Lukkiutumisen havaitsemisen helpottamiseksi on oleellista, että resurssien käytölle ei ase-
teta rajoituksia. Myös järjestelmä asetetaan ajamaan ajoittaisesti lukkiutumisen havaitse-
misalgoritmi. Kun algoritmi on ajettu läpi, merkitsemättömät prosessit ovat lukkiutuneet.
[8]
Lukkiutumisen ehkäiseminen tarkoittaa yksinkertaistettuna sitä, että edellä lueteltujen luk-
kiutumisen ehtojen tapahtuminen pyritään estämään ja täten ehkäisemään lukkiutumista.
Ehkäisyn kannalta on riittävää, että vähintään yksi ehto ei ole voimassa jokaisena prosessi-
en suorituksen hetkenä. Poissulkemisenehdon ehkäisy tapahtuu tekemällä mahdollisimman
monista resursseista yhteiskäyttöisiä (spooling). Kaikkia resursseja ei kuitenkaan ole mah-
dollista käyttää yhtä aikaa, joten poissulkemisehtoa ei voida täysin poistaa kaikista järjes-
telmistä. Varaus–odotusehdon toteutumista voidaan ehkäistä vaatimalla, että prosessi varaa
kerralla kaikki tarvitsemansa resurssit ja vapauttaa jo varaamansa resurssit, jos jonkin re-
11
surssin varaus ei onnistu ja jää odottamaan kunnes kaikki sen tarvitsemat resurssit ovat
vapaita. [8, 9, 10]
Irrottamattomuusehdon toteutuminen voidaan ehkäistä kolmella eri tavalla: 1) otetaan va-
rattua resurssia pyytävältä prosessilta sillä jo olevat varaukset pois ja vaaditaan, että se
pyytää niitä uudestaan yhdessä uusien resurssipyyntöjensä kanssa, 2) otetaan varattu re-
surssi väkisin pois sen haltijalta ja annetaan pyytäjälle, 3) pakotetaan prosessi peruutta-
maan varauksensa. Silmukkaodotusehdon ehkäisy tapahtuu vaatimalla, että resurssit vara-
taan aina tietyssä järjestyksessä. Resurssit voidaan esimerkiksi priorisoida ja vaatia, että
resurssit tulee aina varata matalimmasta prioriteetista alkaen eikä prosessi voi varata re-
surssia, jonka prioriteetti on matalampi kuin korkein sen jo varaaman resurssin prioriteetti.
[8, 10]
Lukkiutumisen välttämiseen tähtäävässä toiminnassa pyritään sallimaan välttämättömien
ehtojen toteutuminen, mutta pidetään samanaikaisesti huolta, ettei järjestelmä voi joutua
lukkiutumistilaan. Esimerkiksi prosessin pyytäessä resurssia, tehdään joka kerta arvio siitä
voiko resurssin myöntäminen johtaa lukkiutumistilaan ja kielletään resurssin saanti mikä
näin voisi tapahtua. Kun jokin resurssi vapautuu, tehdään uusi arvio vieläkö aiemmin pyy-
detyn resurssin myöntäminen voisi johtaa lukkiutumiseen, ja myönnetään resurssi, jos luk-
kiutumisen vaaraa ei enää havaita. [8, 9]
Kaikki pakottamistoimet ovat aina vaarallisia datan säilymisen ja oikeellisuuden kannalta.
Oikein suunnitellussa järjestelmässä yksinoikeudet resursseihin ovat siellä syystä ja resurs-
sien pois ottamisella prosessilta, ennen kuin se on saanut suoritettua operaationsa loppuun,
on yleensä huonot seuraukset ainakin prosessin itsensä kannalta. Huonoimmassa tapauk-
sessa operaation keskeyttäminen korruptoi käsitellyn datan käyttökelvottomaksi koko jär-
jestelmän kannalta tai kadottaa sen kokonaan. Kuvassa 1 on taulukoitu eri lukkiutumisen
havaitsemis-, ehkäisy- ja välttämismenetelmien hyötyjä ja haittoja englanniksi. [6, 12]
12
Kuva 1: Yhteenveto lukkiutumisen havaitsemis-, ehkäisy- ja välttämismenetelmien hyödyistä ja hai-
toista
3.3 Aterioivien filosofien ongelma
Aterioivien filosofien ongelmassa viisi filosofia istuu pyöreän pöydän ympärillä. Jokaisella
filosofilla on edessään lautasellinen spagettia ja yksi haarukka jokaisen lautasen välissä,
joka on havainnollistettu kuvassa 2. Kun filosofi on ajatellut tarpeeksi pitkään, tulee hän
nälkäiseksi ja yrittää ottaa haarukan lautasensa molemmilta puolilta. Jos filosofi saa kaksi
haarukkaa, alkaa hän syömään. Kun filosofi on tullut kylläiseksi, asettaa hän haarukat ta-
kaisin paikoilleen ja jatkaa ajattelua. Mikäli filosofi ei saa kahta haarukkaa, jää hän odot-
13
tamaan, että hänen tarvitsemansa haarukka (haarukat) vapautuisi. Odottaessaan filosofi
pitää kädessään mahdollisesti jo saamaansa haarukkaa. [9]
Kuva 2: Aterioivat filosofit
Asetelma johtaa lukkiutumiseen, kun esimerkiksi jokaisella filosofilla on yksi haarukka
kädessään. Tällöin kukaan ei pääse syömään eikä siten ikinä vapauta varaamaansa haaruk-
kaa. Lukkiutumisesta riippumatta saattaa myös nälkiintymistä esiintyä. Nälkiintyminen on
tilanne, jossa yksi tai useampi filosofi ei saa syötyä, koska vierustoverit pitävät haarukat
varattuna. [9]
Ongelmaa voidaan yrittää ratkaista esimerkiksi asettavalla sääntö, että filosofin pitää pa-
lauttaa haarukka pöydälle odotettuaan viisi minuuttia ja tämän jälkeen odottaa vielä viisi
minuuttia ennen kuin voi uudelleen yrittää saada haarukoita haltuunsa. Tämä järjestely
poistaa lukkiutumisen riskin, mutta jättää mahdollisuuden joutua livelockiin mikäli kaikki
viisi filosofia tulevat huoneeseen samaan aikaan ja suorittavat kaikki toiminnot täsmälleen
samanaikaisesti. [9, 13, 14]
14
3.3.1 Ratkaisumalli: Tarjoilija
Suhteellisen yksinkertainen ratkaisu on tuoda tarjoilija pöytään. Filosofien täytyy kysyä
häneltä lupa haarukan ottamiseen. Koska tarjoilija tietää mitkä haarukat ovat käytössä,
hänen on mahdollista välttää lukkiutumiset. Neljän haarukan ollessa käytössä haarukkaa
pyytävä filosofia ei saa lupaa ottaa sitä ennen kuin yksi haarukka vapautuu. Logiikka on
pidetty yksinkertaisena määrittelemällä, että filosofi yrittää aina ottaa vasemmanpuoleisen
haarukan ennen oikeanpuoleista. [13, 14]
3.3.2 Ratkaisumalli: Hierarkkiset resurssit
Toinen yksinkertainen ratkaisu saavutetaan määrittelemällä resursseille hierarkia ja päät-
tämällä, että resursseja pitää pyytää järjestyksessä ja ne pitää palauttaa päinvastaisessa jär-
jestyksessä. Aterioivien filosofien ongelmassa haarukat numeroidaan yhdestä viiteen ja
jokainen filosofi ottaa ensin pienempinumeroisen ja sitten suurempinumeroisen haarukan.
Sitten filosofi palauttaa ensin suurempinumeroisen ja sen jälkeen pienempinumeroisen
haarukan. Mikäli neljä filosofia poimii samanaikaisesti haarukan, vain suurinumeroisin
haarukka jää pöydälle ja viides filosofi ei voi ottaa haarukkaa. Lisäksi vain yhdellä filoso-
filla on mahdollisuus ottaa suurinumeroisin haarukka, joten hän voi syödä kahdella haaru-
kalla. Syötyään hän laittaa ensin suurinumeroisemman haarukan pöydälle ja tämän jälkeen
pienempinumeroisen antaen toiselle filosofille mahdollisuuden syödä.
Vaikka resurssien hierarkkinen jako estää lukkiutumisen, niin se ei silti ole aina paras rat-
kaisu. Varsinkaan tilanteissa, joissa tarvittavia resursseja ei etukäteen tiedetä. [13, 14]
3.4 Pankkiirin algoritmi
Pankkiirin algoritmi on Edsger Dijkstran resurssien jakoon ja lukkiutumisen estoon kehit-
tämä algoritmi, joka simuloi resurssien maksimijakomääriä ja siten tarkistaa muiden odot-
tavien toimintojen mahdolliset lukkiutumistilanteet. Simuloinnin jälkeen algoritmi päättää
onko jakoa turvallista jatkaa vai ei. [8]
Käyttöjärjestelmä suorittaa algoritmin aina kun prosessi pyytää resurssia. Algoritmi estää
lukkiutumisen estämällä tai lykkäämällä pyyntöä mikäli se huomaa, että pyynnön hyväk-
syminen saattaa johtaa tilaan, jossa lukkiutumisia voi syntyä. Toimiakseen pankkiirin algo-
ritmin tarvitsee tietää kolme asiaa: kuinka paljon mikin prosessi voi pyytää tiettyä resurs-
15
sia, kuinka paljon mikin prosessi pitää hallussaan kustakin resurssista ja kuinka paljon ku-
takin resurssia on jäljellä. [8]
Tilaa pidetään turvallisena, mikäli kaikkien prosessien on mahdollista suorittaa tehtävänsä
loppuun. Koska systeemi ei voi tietää milloin prosessi on suoritettu tai miten monia re-
sursseja se on siihen mennessä pyytänyt, se olettaa että lopulta prosessit yrittävät saada
haltuunsa niille määritellyn maksimimäärän resursseja ja lopettavat pian sen jälkeen. Suu-
rimmassa osassa tapauksia tämä on järkevä päätelmä, sillä järjestelmä ei ole erityisen huo-
lestunut siitä milloin prosessit suoritetaan loppuun. Tämän päätelmän pohjalta algoritmi
päättelee onko tila turvallinen yrittämällä löytää hypoteettisen sarjan pyyntöjä prosesseilta,
jotka mahdollistaisivat jokaisen prosessin hankkia käyttöönsä maksimimäärän resursseja ja
sitten terminoitua. Mikäli tällaista sarjaa ei löydy, niin algoritmi päättelee, ettei tila ole
turvallinen. [8]
Kuten monet muutkin algoritmin, niin pankkiirin algoritmikin sisältää joitain kompromis-
seja. Sen täytyy erityisesti tietää kuinka paljon mitäkin resurssia prosessi voi pyytää, mutta
monissa systeemeissä tämä tieto ei ole saatavilla, tehden algoritmin käyttökelvottomaksi.
On myös epärealistista olettaa, että prosessien määrä pysyy vakiona, sillä suurimmassa
osassa systeemejä prosessien määrä vaihtelee dynaamisesti. Sitä paitsi käytännön systee-
min kannalta ei ole järkevää odottaa, että prosessi vapauttaa kaikki resurssinsa, sillä siinä
saattaa kestää tunteja tai jopa päiviä. [8, 15]
3.5 Lukkiutumisesta palautuminen
Lukkiutumisesta palautumiseen on olemassa neljä pääsääntöistä palautumisstrategiaa. En-
simmäinen strategia sisältää kaikkien lukkiutuneiden prosessien keskeyttämisen. Toinen
strategia perustuu lukkiutuneiden prosessien peruuttamiseen johonkin aiempaan tarkistus-
pisteeseen ja prosessien aloittamiseen uudelleen. Kolmas strategia pohjautuu prosessien
keskeyttämiseen yksi kerrallaan jonkin prioriteetin mukaan, kunnes lukkiutuminen purkau-
tuu. Neljännessä strategiassa vapautetaan väkisin lukkiutuneilta prosesseilta resursseja jon-
kin prioriteetin mukaisesti yksi kerrallaan, kunnes lukkiutumista ei enää havaita. [10, 11]
16
Prosessien keskeyttämisessä voidaan käyttää esimerkiksi seuraavia kriteereitä: [10, 11]
− vähiten prosessoriaikaa tähän mennessä kuluttanut prosessi
− vähiten tulostetta (output) tuottanut prosessi
− prosessi, jonka suorituksen ennakoidaan kestävän pisimpään
− vähiten tähän mennessä resursseja varannut prosessi
− pienimmän prioriteetin prosessi
Jokainen lukkiutumisesta palautumismenetelmä aiheuttaa häiriöitä prosessien toiminnalle
ja pahimmissa tapauksissa kadottaa tai korruptoi dataa siinä sivussa. Ensisijaisesti lukkiu-
tumiset tulisi estää ennen kuin niitä pääsee syntymään. Toissijaisesti tulisi käyttää proses-
sien palauttamista tunnettuun tarkistuspisteeseen ja käynnistämistä uudelleen koska tällöin
prosessille ei yleensä aiheudu pysyvää vauriota.
17
4. Nälkiintyminen
Nälkiintyminen on moniajoon liittyvä ongelma, jossa prosesseilta kielletään tarpeelliset
resurssit, joita ilman prosessia ei voida suorittaa loppuun. Nälkiintyminen on lopputulok-
seltaan hyvin samantyyppinen lukkiutumisen kanssa, jossa kaksi tai useampi prosessi odot-
taa jonkun toisen prosessin käytössä olevia resursseja. Lukkiutuminen on nälkiintymisen
erikoistilanne, kuten on myös livelock. Livelock:ssa prosessit voivat vaihtaa tilaansa, toisin
kuin lukkiutumisessa, mutta kummassakaan prosessit eivät pääse etenemään. Yleensä on-
gelmia, joissa prosesseilta on kielletty niiden tarvitsemat resurssit, eikä niissä tapahdu
minkäänlaisia tilamuunnoksia, kutsutaan lukkiutumisongelmiksi ja muihin vastaaviin on-
gelmiin viitataan nälkiintymisenä. [16]
Ongelma johtuu yleensä järjestelmän ytimessä (kernel) sijaitsevasta vuorotusalgoritmista
(scheduling algorithm), jonka tehtävä on jakaa resursseja niin, että prosesseilta ei tarkoi-
tuksellisesti puutu tarvittavia resursseja. [16]
Monilla käyttöjärjestelmien vuorottajilla on ymmärrys priorisoinnista. Korkeamman priori-
teetin omaava prosessi suoritetaan ennen matalamman prioriteetin prosessia, mutta mikäli
tärkeämpää prosessia ei koskaan pysäytetä, saattaa matalampi prosessi jäädä suorittamatta
ja kärsiä nälkiintymisestä. Moderneissa vuorotusalgoritmeissa on normaalisti koodi, joka
takaa prosesseille vähimmäismäärän tärkeistä resursseista. Näin vältetään prosessien näl-
kiintyminen. [16]
18
5. Yhteenveto
Keskityimme työssämme laajasti poissulkemisen ongelmaan ja pyrimme tuomaan esille
kaikki mahdolliset keinot myös tilanteiden ennalta ehkäisemiseksi ja niiden ratkaisemisek-
si, jos ne ovat päässeet jo muodostumaan. Esittelimme tämän hetken toimivimmat ja ylei-
sesti käytetyimmät algoritmit asiaan liittyen, ja niihin liittyvät pakolliset kompromissit.
Ongelmien ratkaisemiseksi ei ole mitään itsestään selvää ja aina toimivaa ratkaisua, vaan
suunnittelemalla asiat etukäteen tarkasti ja ajatuksella voidaan päästä hyviin kompromis-
seihin ratkaisujen osalta.
Käyttöjärjestelmien rakenteen muuttuessa yhä monimutkaisemmaksi vain aika näyttää
kasvavatko käsiteltyjen ongelmatilanteiden määrät huomattavasti vai saadaanko niiden
ratkaisumalleja kehitettyä yhä tehokkaammiksi, ja täten myös parannettua niiden ennalta-
ehkäisyn mahdollisuuksia.
19
Lähteet
[1] Vesanen, Ari: Rinnakkainen ohjelmointi: luennot ”Poissulkevuusongelma”, ”Rinnak-
kaisuuden perusrakenteita: Semaforit ja Monitorit”.
(http://www.tol.oulu.fi/~avesanen/Rinn_Ohjelm/Luennot/ 4.3.2009)
[2] Haikala, Ilkka; Järvinen, Hannu-Matti: Käyttöjärjestelmät, 2004. Talentum. ISBN 952-
14-0851-0
[3] Ikonen, Leena: Unix and System Programming, 2008.
(http://www.it.lut.fi/kurssit/08-09/CT20A3000/lectures/luento9_nup.pdf 4.3.2009)
[4] Ikonen, Leena: Unix and System Programming, 2008.
(http://www.it.lut.fi/kurssit/08-09/CT20A3000/lectures/luento10_nup.pdf 4.3.2009)
[5] Knuutila, Timo: luento “Rinnakkainen ohjelmointi”.
(http://guardian.cs.utu.fi/knuutila/Courses/okp/luennot/rinnakkainen.pdf 3.3.2009)
[6] Roy, Patricia: Manatee Community College, Venice, FL, 2008. Prentice Hall.
(http://www.cs.ucf.edu/~lboloni/Teaching/COP4600_Spring2009/slides/06-Deadlocks.ppt
3.3.2009)
[7] Koskinen, Aaro: Menetelmä hajautettujen järjestelmien mallinnukseen ja suorituskyvyn
analysointiin. (http://www.cs.helsinki.fi/u/marttine/Rios05/Luennot/rios05-04.ppt
4.3.2009)
[8] Vainio, Aki: Lukkiutuminen. (http://lipas.uwasa.fi/~h79423/kj/ppt/Lukkiutuminen.ppt
3.3.2009)
[9] Häkkinen, Auvo; Marttinen, Liisa: Lukkiutuminen.
(http://www.cs.helsinki.fi/u/marttine/Rios05/Luennot/rios05-04.ppt 4.3.2009)
[10] Concurrency: Deadlock and Starvation, Chapter 6.
(http://thns.tsinghua.edu.cn/jsj00004/Chap6.ppt 3.3.2009)
[11] Concurrency: Deadlock and Starvation (http://oc.its.ac.id/ambilfile.php?idp=712
3.3.2009)
20
[12] Deadlocks and Dining Philosophers, (http://www.neiu.edu/~jasittle/cs308/ 3.3.2009)
[13] Dijkstra, E. W.: Hierarchical ordering of sequential processes, 1971. Acta Informatica.
1(2): s. 115-138.
[14] Silberschatz, Abraham; Peterson, James L.: Operating Systems Concepts, 1988.
Addison-Wesley. ISBN 0-201-18760-4.
[15] Lubomir, F. Bic; Shaw, Alan C.: Operating System Principles, 2003. Prentice Hall.
ISBN 0-13-026611-6. (http://www.cs.utexas.edu/users/EWD/ewd03xx/EWD310.PDF)
[16] Tanenbaum, Andrew: Modern Operating Systems, 2001. Prentice Hall.