320 likes | 506 Views
k=k+1; i=i-1;. k=k+1; i=i-1. Prosessit voivat häiritä toisiaan!. yhteinen muisti. prosessi j. prosessi i. i: 10. k:. 5. Prosessien tai säikeiden yhteistoiminta pitää varmistaa!. Liisa Marttinen. puskurin käsittely. kirjoittamisen ja lukemisen tahdistus.
E N D
k=k+1; i=i-1; k=k+1; i=i-1 Prosessit voivat häiritä toisiaan! yhteinen muisti prosessi j prosessi i i: 10 k: 5 Prosessien tai säikeiden yhteistoiminta pitää varmistaa! Liisa Marttinen
puskurin käsittely kirjoittamisen ja lukemisen tahdistus Prosessien toiminta pitää jotenkin synkronoida! Esim. tuottaja ja kuluttaja,joiden välissä on puskuri tuottaja kirjoittaa puskuriin kuluttaja lukee puskurista Mitä ongelmia voi syntyä? Mitä toimintoja tässä pitää synkronoida? Liisa Marttinen
Ratkottavien ongelmien aiheita antavat… • Rinnakkainen data poissulkeminen • Esim. yhteinen puskuri datan ajantasaisuus • read - update - write • Rinnakkainen suoritussynkronointi • Esim. tuota - kuluta • Resurssien jakelu lukkiutuminen • Joku huutaa lisää • Vuorojen jakelu nälkiintyminen • Onneton prioriteetti Auvo Häkkinen
Täysin Poissulkeminen erillisetKilpailu Lukkiutuminen prosessit Nälkiintyminen Prosessit Poissulkeminen epäsuorastiYhteistyö Lukkiutuminen tietoisia toisista Yhteinen muisti Nälkiintyminen Datan ajantasaisuus Prosessit suorastiYhteistyö Lukkiutuminen tietoisia toisista Sanomanvälitys Nälkiintyminen ks. Stallings Tab 5.1 • Suoritusjärjestys / ajoitus • Prosessin lopputulos Auvo Häkkinen
tila muutoksen jälkeen Atomisuus (atomic action) • alkutila tilamuutos välitiloja ei näy • yksittäinen konekäsky on atominen • usean konekäskyn vaatima muutos = kriittinen alue (critical section) on tehtävä ’atomiseksi’ keskinäisellä poissulkemisella (mutual exclusion) • muut prosessit eivät pääse käsittelemään tilamuutoksen muuttujia eli suorittamaan omaa kriittista aluettaan Liisa Marttinen
Entry protocol# varaa < kriittinen koodialue ># käytä (exclusive!) Exit protocol# vapauta Poissulkeminen • Ohjelman perusmalli process CS[i=1 to n] { # n rinnakkaista prosessia while (true) { ei kriittistä koodia ei kriittistä koodia; } } • Ohjelmoi kriittiset alueet lyhyiksi! • Vain välttämätön
deadlock livelock Halutut ominaisuudet Poissulkeminen • Vain yksi prosessi kerrallaan suorituksessa kriittisellä alueella Ei lukkiutumisvaraa, ei ‘elohiirtä’ • Jos useita sisäänpyrkijöitä, jotain onnistaa Ei tarpeettomia viipeitä • Jos alue vapaa, pääsy sallittava Lopulta onnistaa, ei ‘nälkiintymistä’ • Kukaan ei joudu odottamaan ikuisesti 3 safety properties + liveness property
Lukkomuuttujat, Spin Locks • Boolean-muuttuja lock • Lock== true kriittinen alue varattu (in1 V in2 V … V inN) • lock==false kriittinen alue vapaa • Entry protocol while (lock) ; # aktiivinen odotus, “pörrää” # check again if (!lock)# busy loop lock=true; • Exit protocol lock=false;
Test-and-Set-käsky • Oma konekielen käsky • atominen laitetason suoritus (execute-vaihe) • argumentti: lukkomuuttuja • boolean paluuarvo • TS L • merkitys: < temp=L; L=0; if (temp==1) jump *+2; > merkitään varatuksi! • Käyttö: • LOOP: TS L JUMP LOOP ....... Saa edetä! Jää odottamaan!
LOCK(L);# varaa < kriittinen alue ># käytä (exclusive!) UNLOCK(L);# vapauta • Poissulkeminen lukkomuuttujaa käyttäen • lock L=1;# käytä lukitsemaan tiettyä kriittistä aluetta • # sopimus prosessien kesken! • process CS [i=1 to N] { # n rinnakkaista! • while (true){ • ei kriittistä koodia; • ei kriittistä koodia; • } • } • Tulkinta: L=1 yhdellä lupa edetä
semafori S alkuarvo P(S) S.arvo V(S) S.jono Semaforit • P()aka WAIT() aka Down() • jos kriittinen alue vapaa, lukitse se ja jatka eteenpäin • jos kriittinen alue varattu, odota • V()aka SIGNAL() aka Up() • jos joku odotusjonossa, päästä joku etenemään muuten vapauta kriittinen alue • atomisia public private public private
P(mutex);# varaa < critical section ># käytä (exclusive!) V(mutex);# vapauta • Poissulkeminen semaforia käyttäen • sem mutex=1;# vain perinteinen muuttujan nimi • process CS [i=1 to N] { # rinnakkaisuus! • while (true){ • ei kriittistä koodia; • ei kriittistä koodia; • } • } • yksi semafori kullekin erilliselle kriittiselle alueelle • huomaa oikea alkuarvo
Prosessi P1 käskyjä… kerro tapahtumasta käskyjä… Prosessi P2 käskyjä… odota tapahtumaa käskyjä... Ehtosynkronointi • Tapahtuma: “mikä tahansa kiinnostava” puskuri_täynnä, io_valmis, laskenta valmis, kriittinen alue vapaa • (Looginen) tapahtuma semaforimuuttuja • Kumpi ehtii ensin synkronointikohtaan? tarvitsee paikan missä odottaa (~jonottaa)
Tuottaja tuota A… V(A_ready); … Kuluttaja … P(A_ready); kuluta A… • Synkronointi semaforia käyttäen • sem A_Ready = 0; • 0 ”ei ole tapahtunut”, 1 ”on tapahtunut” • Kumpi ehtii ensin? • Oikea alkuarvo?
Puomisynkronointi • sem arrive1 = 0, arrive2 = 0; • process Worker1 { • …käsittele alkuosa 1… • V(arrive1);# lähetä synkronointitapahtuma • P(arrive2);# odota toista prosessia • …käsittele loppuosa 1… • } • process Worker2 { • …käsittele alkuosa 2… • V(arrive2);# lähetä synkronointitapahtuma • P(arrive1); # odota toista prosessia • …käsittele loppuosa 2… • } Huomaa järjestys!
Kilpailutilanne koordinaattori V(arrive); P(continue); P(arrive) OK N kertaa! V(continue) N kertaa; V(arrive); P(continue); Mitä tässä voi tapahtua?
Halkaistu binäärisemafori(Split binary semaphore) • semaforit empty ja full • binäärisemaforeja, koska voivat saada vain arvoja 0 ja 1 • koska aina toisella niistä on arvona 1 ja toisella 0, niin niiden voidaan katsoa olevan yhdestä semaforista halkaistuja osia • voidaan halkaista myös useampaa osaan: N kappaletta semaforeja, joista aina yhdellä on arvona 1 ja muilla 0 • halkaistu binäärisemafori huolehtii myös keskinäisestä poissulkemisesta: • vain yksi kerrallaan pääsee suorittamaan sen suojaamaa kriittistä aluetta, jos • yhdellä semaforilla alkuarvona 1, muilla 0 • kaikilla prosesseilla koodissaan ensin P-operaatio semaforiinsa • Se prosessi (yksi niistä prosesseista) aloittaa, jonka P-operaation kohteen semaforin arvo on 1.
Viestikapulan välitys (Baton passing) • semafori ~ viestikapula; • koska semaforit e, r ja w muodostavat jaetun binäärisemaforin, niin kulloinkin yhdellä niistä on arvo 1 ja muilla arvo 0 • Vain yksi etenee kerrallaan kriittisillä alueilla • pyydettävä etenemislupaa: P(e) • se etenee, joka ‘saa’ haltuunsa semaforin e • Muiden odotettava • täysin uusi lukija tai kirjoittaja: P(e) • vuoroaan jonottamaan jääneet lukijat ja kirjoittajat: Jos etenijän pyyntöön ei voi suostua: • Lukijat: V(e); P(r) (jää odottamaan lukijan vuoroaan) • Kirjoittajat: V(e); P(w) (jää odottamaan kirjoittajan vuoroaan)
Päästetäänkö lukija, kirjoittaja vai uusi tulija? laskurit dr ja dw kertovat odottavien lukumäärän. Entry- semaforin e jonossa odottavat Semaforin r jonossa odottavat lukijat Voiko mennä lukemaan / kirjoittamaan?Aina vapautetaan entry-semafori seuraavalle! lopputoimet: poistutaan ja valitaan seuraava kriittiselle alueelle pääsijä. Semaforin w jonossa odottavat kirjoittajat tietokannan käsittely
DELAY: Älä jätä prosessia Blocked-tilaan tärkeä semafori kiinni! SIGNALNEXT: Herätä odottaja ja jätä kriittinen alue kiinni (baton passing). Vapauta semafori , jos ei ole odottajia! • Resurssien hallinta, Yleinen ratkaisu (baton passing) • pyydä(parametrit) P(mutex); # poissulkeminen if (pyyntöön ei voi suostua) DELAY; # odota semaforissa anna resurssi; SIGNALNEXT; • vapauta(parametrit) P(mutex); palauta resurssi; SIGNALNEXT; • DELAY ~ • V(mutex), P(odotussemafori) • SIGNALNEXT ~ • V(odotussemafori) else V(mutex)
Palvelujärjestys • Semaforin jonot aina FCFS • Ongelma? Jäljellä 10 sivutilaa, eka haluaa 12, toka 5! • Voiko semaforiin liittää prioriteetin? • Jonotusjärjestys? • Baton passing- tekniikka: eri luokille omat jonot • Montako erilaista? Dynaaminen vuorottelu? • Kaikki mahdolliset varattavat sivutilakoot (1… N) • Ratkaisu: yksityiset semaforit + oma jono • Kullekin prosessille oma semafori, jossa odottaa yksin • Vuoron antamiseen käytettävä tietorakenne (jono) erikseen • alkiossa semafori ja yleensä tietoa, jonka perusteella valitaan • Vuoron antaja valitsee sopivan semaforin vuorojonosta, ja päästää liikkeelle semaforissa odottavan asiakkaan
Prosessien synkronointi monitorilla • poissulkeminen (mutual exclusion) • implisiittistä • vain yksi prosessi voi olla aktiivisena monitorissa eli suorittamassa jotain monitorin proseduuria • ei useaa prosessia suorittamassa samaa proseduuria • ei useaa prosessia suorittamassa eri proseduureja • ohjelmoijan ei siis tarvitse huolehtia tästä • ehtosynkronointi • ohjelmoijan vastuulla; vain ohjelmoija tietää, millaista synkronointia prosessien välillä tarvitaan • täytyy ohjelmoida eksplisiittisesti • ehtomuuttujia (condition variables) käyttäen
Kilpailutilanne! P5 P2 P4 while? if? (Odotusehto) WAIT(A); P1, P3,P5 A SIGNAL(A); Odotusehto ==false; Condition passing: jätetään odotusehto ’päälle’ => uudet tarkastavat ja menevät odottamaan odotuksesta vapautettu ei enää tarkasta ehtoa (IF!!)
Kanavat (Andrews) • Yhteinen ’postilaatikko’ • jono sanomia, FIFO • kaikki kanavan sanomat rakenteeltaan samanlaisia • chan ch(type1 id1, …, typen idn) • ch: kanavan nimi • typei idi: sanoman osien tyypit, ja nimet (saavat puuttua) • Esim. • chan input(char); • chan disk_access (int cylinder, int block, int count, char* buffer); • chan result[n] (int); # kanavien taulukko
Ei ota kantaa minkä prosessin kanssa kommunikoi! • Operaatiot • send kanava(lauseke1, … , lauseken) • lähetä sanoma kanavaan • receive kanava(muuttuja1 , … , muuttujan) • vastaanota sanoma kanavasta • empty(kanava) • tarkista onko kanava tyhjä sanomista • Esim. • send disk_access(cylinder+2, block, count, buf) • receive result[i](sum) • empty(input)
process Server { int clientID; declaration of other permanent variables; initialization code; while (true) { receive request (clientID, input); code from body of operation op; send reply[clientID] (result) } Monitori palvelinprosessi monitor Mname { declaration of permanent variables; intialization code; procedure op (formals) { body of op; } }
Asiakkaat ja monen palvelun palvelija • Pyyntökanava • Asiakkaiden tuntema julkinen kanava • käytännössä: IP-osoite ja porttinumero • Yksi pyyntökanava sanoma kanavaan tulkitse tyyppi, valitse palvelu tai dedikoitu kanava kullekin palvelulle valitse palvelu lähetä sopivaan kanavaan • Vastauskanava • Palvelijan tuntema (staattinen) [Tällä kurssilla] • Jokaisella asiakkaalla oma yksityinen • kerro oma identiteetti pyyntösanomassa • Asiakas kertoo pyynnössä (dynaaminen) • käytännössä: oma IP-osoite ja porttinumero
process secretary { co while (true) { receive request(philo); P(mutex); state[philo]=HUNGRY; consider_allocation_to(philo); V(mutex); } // while (true) { receive release(philo); P(mutex); state[philo]=THINKING; consider_allocation_to(philo-1); consider_allocation_to(philo+1); V(mutex); } oc } chan request(int), release(int), reply[5]( ); sem mutex=1; Aterioivat filosofit + sihteeri, dedikoidut kanavat • process philosofer[i=0 to 4] { • while (true) { • think(); • send request(i); • receive reply[i](); • eat(); • send release(I); • } Miten odottaa yhtä aikaa kahdesta eri kanavasta? Huomaa rinnakkaisuus!
Monitori vs. Palvelija • proseduurikutsu vs. kanava & sanoma • poissulkeminen • monitori: implisiittisesti, ei semaforeja! • palvelija: palvele yksi asiakas kerrallaan, uudet pyyntösanomat jäävät kanavaan • synkronointi • monitori: jos ei saa edetä, wait(ehtomuuttuja) • kutsunut prosessi nukahtaa • palvelija: jos ei saa edetä, laita sisäiseen jonoon • palvelija ei voi nukahtaa!
Klassisia malleja • Bounded buffer(tuottaja – kuluttaja, suodin) • Resurssien allokointi(asiakas – palvelija) • Lukijat/kirjoittajat(luokan vuorot) • SJN-skedulointi(priority wait) • Aikaviipaleet ja ajastimet(vuorottamispalvelu) • Nukkuva parturi(prosessien kohtaaminen) • Aterioivat filosofit (lukkiuma) (hajautettu resurssien jakelu)
Arkkitehtuureja • liukuhihna, suodin • tuottaja – kuluttaja • asiakas – palvelija • vertaistoimijat (peer-to-peer,P2P) • monipuolisemmat rakenteet: heartbeat yms. • ryhmä: keskitetty, rengas, symmetrinen
Evaluoi • Oikeellisuus • Suorituspolkujen analyysi • Tilamallit • Suorituskyky • Yleisrasite • Komponentti • Kommunikointi / ryhmän kommunikointi • Rinnakkaisuusaste Selvitä aina, kuinka järjestelmä käyttäytyy!