03.05.2013 Views

Concurrency en race condities

Concurrency en race condities

Concurrency en race condities

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

<strong>Concurr<strong>en</strong>cy</strong>


Concurr<strong>en</strong>te process<strong>en</strong><br />

Con-cur-r<strong>en</strong>t adj. 1.occurring or existing at the same time<br />

or side by side. 2. ....<br />

(The RANDOM HOUSE college dictionary)<br />

<strong>Concurr<strong>en</strong>cy</strong> betek<strong>en</strong>t hier dat process<strong>en</strong><br />

gelijktijdig of naast elkaar actief zijn.<br />

– Meerdere process<strong>en</strong> op e<strong>en</strong> computer.<br />

– Meerdere threads binn<strong>en</strong> e<strong>en</strong> proces.<br />

– Meerdere process<strong>en</strong> in e<strong>en</strong> gedistribueerde<br />

omgeving.<br />

– E<strong>en</strong> over meerdere computers gedistribueerde taak.<br />

College OS 2010 – 2011 2


Concurr<strong>en</strong>te process<strong>en</strong><br />

• Concurr<strong>en</strong>tie geeft noodzaak tot<br />

– Communicatie<br />

• Overdracht van informatie<br />

– Synchronisatie<br />

• Wacht<strong>en</strong> op resultaat van e<strong>en</strong> andere taak<br />

– Coördinatie<br />

• Toegang tot gedeelde resources<br />

College OS 2010 – 2011 3


Niet-atomaire opdracht<strong>en</strong><br />

• Bij gelijktijdige b<strong>en</strong>adering van e<strong>en</strong> item door<br />

twee tak<strong>en</strong>/threads kunn<strong>en</strong> problem<strong>en</strong><br />

optred<strong>en</strong>.<br />

• B.v. C-expressie: n++<br />

• Pseudo-assembler:<br />

mov rega, n # inhoud n naar register a<br />

inc rega # increm<strong>en</strong>t op register a<br />

mov n, rega # inhoud register a naar n<br />

• Drie operaties. E<strong>en</strong> interrupt, dus e<strong>en</strong> threadswitch<br />

kan overal optred<strong>en</strong>.<br />

• n++ is niet-atomair.<br />

College OS 2010 – 2011 4


Mogelijke executie<br />

• Tel aantal aanwezig<strong>en</strong>: n++ bij ingang,<br />

n-- bij uitgang.<br />

• Thread “in” OS Thread “uit”<br />

mov rega, n (interrupt)<br />

save rega<br />

dispatch thread 2<br />

mov rega, n<br />

dec rega<br />

mov n, rega<br />

restore rega<br />

dispatch thread 1<br />

inc rega<br />

mov n, rega<br />

• Resultaat: n is één keer opgehoogd,<br />

vertrekk<strong>en</strong>de bezoeker is gemist.<br />

College OS 2010 – 2011 5


Race <strong>condities</strong><br />

• Relatieve executie-snelheid van process<strong>en</strong> is<br />

onbepaald.<br />

• Fout kan optred<strong>en</strong> afhankelijk van toevallige<br />

volgorde van uitvoering. Alle<strong>en</strong> kans nul op<br />

e<strong>en</strong> fout is acceptabel.<br />

• We noem<strong>en</strong> dit “<strong>race</strong> conditie”<br />

• Andere voorbeeld<strong>en</strong>:<br />

– wait + signal<br />

– readers / writers<br />

College OS 2010 – 2011 6


Kritieke sectie<br />

• Bij toegang tot geme<strong>en</strong>schappelijke<br />

variabel<strong>en</strong> <strong>race</strong> conditie mogelijk.<br />

• Deel van programma heet “kritieke sectie”<br />

• Aantal tak<strong>en</strong> in kritieke sectie moet beperkt:<br />

– Toestemming nodig bij binn<strong>en</strong>komst<br />

– Afmeld<strong>en</strong><br />

• Hoe?<br />

– B.v. met JAVA synchronized methods - maar hoe<br />

werk<strong>en</strong> die?<br />

College OS 2010 – 2011 7


Afzett<strong>en</strong> interrupts<br />

• Voorkomt wissel<strong>en</strong> naar andere taak tijd<strong>en</strong>s<br />

kritieke sectie<br />

• Maar<br />

– Vertraagt afhandeling belangrijke interrupts<br />

– Mag dus maar heel ev<strong>en</strong>tjes<br />

– Taak mag nooit in deze kritieke sectie blijv<strong>en</strong><br />

“hang<strong>en</strong>”<br />

– Mag natuurlijk nooit door gebruiker<br />

– Werkt niet voor SMP (Shared Memory<br />

Multiprocessor), Dual- <strong>en</strong> Quad-cores<br />

College OS 2010 – 2011 8


• Produc<strong>en</strong>t<br />

while (1) {<br />

}<br />

produceer(&pdata);<br />

while (beurt !=<br />

Afscherming in software?<br />

produc<strong>en</strong>t); /*wacht*/<br />

buffer = pdata;<br />

beurt = consum<strong>en</strong>t;<br />

• Consum<strong>en</strong>t<br />

while (1) {<br />

while (beurt !=<br />

consum<strong>en</strong>t); /*wacht*/<br />

cdata = buffer;<br />

beurt = produc<strong>en</strong>t;<br />

gebruik(&cdata);<br />

NB. Toek<strong>en</strong>ning van e<strong>en</strong> <strong>en</strong>kel bit/byte/woord kan wel atomair<br />

(maar pas op met de cache!!)<br />

Werkt hier wel, maar dwingt strikte afwisseling af.<br />

Beslissing hangt niet alle<strong>en</strong> van wacht<strong>en</strong>de process<strong>en</strong> af.<br />

}<br />

College OS 2010 – 2011 9


• Eén voor één toelat<strong>en</strong><br />

Eis<strong>en</strong> afscherming<br />

• 100 % betrouwbaar (ge<strong>en</strong> <strong>race</strong><strong>condities</strong>!)<br />

• Ge<strong>en</strong> “starvation”<br />

– “Bounded waiting”: bov<strong>en</strong>gr<strong>en</strong>s aan wachttijd<br />

• er mag maar e<strong>en</strong> eindig aantal andere process<strong>en</strong> voor<br />

gaan<br />

– “Progress”: beslissing over toelating<br />

• betreft alle<strong>en</strong> reeds wacht<strong>en</strong>de process<strong>en</strong><br />

• wordt in eindige tijd g<strong>en</strong>om<strong>en</strong><br />

• Oudste oplossing van Dekker<br />

College OS 2010 – 2011 10


Poging 1<br />

<strong>en</strong>um {false, true} nul_wil = false, e<strong>en</strong>_wil = false;<br />

• Thread 0<br />

while (e<strong>en</strong>_wil);<br />

nul_wil = true;<br />

/* kritieke sectie 0 */<br />

nul_wil = false;<br />

• Thread 1<br />

Wat gaat er mis?<br />

while (nul_wil);<br />

e<strong>en</strong>_wil = true;<br />

/* kritieke sectie 1 */<br />

e<strong>en</strong>_wil = false;<br />

College OS 2010 – 2011 11


Poging 2<br />

<strong>en</strong>um {false, true} nul_wil = false, e<strong>en</strong>_wil = false;<br />

• Thread 0<br />

nul_wil = true;<br />

while (e<strong>en</strong>_wil);<br />

/* kritieke sectie 0 */<br />

nul_wil = false;<br />

• Thread 1<br />

Wat gaat er nu mis?<br />

e<strong>en</strong>_wil = true;<br />

while (nul_wil);<br />

/* kritieke sectie 1 */<br />

e<strong>en</strong>_wil = false;<br />

College OS 2010 – 2011 12


int beurt = 0;<br />

• Thread 0<br />

nul_wil = true;<br />

beurt = 1;<br />

while (e<strong>en</strong>_wil &&<br />

beurt == 1);<br />

/* kritieke sectie 0 */<br />

nul_wil = false;<br />

Oplossing van Peterson<br />

<strong>en</strong>um {false, true} nul_wil = false, e<strong>en</strong>_wil = false;<br />

• Thread 1<br />

e<strong>en</strong>_wil = true;<br />

beurt = 0;<br />

while (nul_wil &&<br />

beurt == 0);<br />

/* kritieke sectie 0 */<br />

e<strong>en</strong>_wil = false;<br />

College OS 2010 – 2011 13


Afscherming voor N tak<strong>en</strong> met arbiter<br />

(Luuk Gro<strong>en</strong>eweg<strong>en</strong>)<br />

<strong>en</strong>um KRITIEK {erin, eruit} IkWil[Nproc], JeMag[Nproc];<br />

Cli<strong>en</strong>t(int N)<br />

{ while(1)<br />

{ /* Niet kritiek */<br />

IkWil[N] = erin;<br />

wachtop(JeMag[N] == erin);<br />

/* kritiek */<br />

IkWil[N] = eruit;<br />

wachtop(JeMag[N] ==<br />

eruit);<br />

}<br />

}<br />

Arbiter()<br />

{ i = 0;<br />

while(1)<br />

{<br />

if (IkWil[i] == erin)<br />

{ JeMag[i] = erin;<br />

wachtop(IkWil[i] ==<br />

eruit);<br />

JeMag[i] = eruit;<br />

}<br />

i = (i + 1) % Nproc;<br />

}<br />

}<br />

College OS 2010 – 2011 14


Busy waiting<br />

• Heet ook wel “spin lock”<br />

• Taak test herhaald waarde van e<strong>en</strong> variabele<br />

– Gebruikt steeds CPU tijd<br />

– Sluit misschi<strong>en</strong> taak in kritieke sectie uit van CPU<br />

– Probleem met name voor wacht<strong>en</strong>de taak met hoge<br />

prioriteit<br />

• Voordeel op multi-processor: ge<strong>en</strong> context<br />

switches bij wacht<strong>en</strong> op taak op andere<br />

processor<br />

College OS 2010 – 2011 15


Afscherming in software<br />

• Peterson‟s <strong>en</strong> Dekker‟s algoritm<strong>en</strong><br />

Bakkerswinkel algoritme<br />

(<strong>en</strong> veel meer, b.v. protocol van Eis<strong>en</strong>berg <strong>en</strong><br />

McGuire)<br />

– Busy waiting, spin locks<br />

– Lastig goed te krijg<strong>en</strong><br />

• Arbiter process<strong>en</strong><br />

– Busy waiting<br />

– Extra proces, veel context switches<br />

– Veel makkelijker<br />

College OS 2010 – 2011 16


Ondersteuning vanuit het systeem<br />

• Je wil twee functies hebb<strong>en</strong> die<br />

– Toegang tot de kritieke sectie verzorg<strong>en</strong><br />

– Met als argum<strong>en</strong>t - welke kritieke sectie<br />

• Het systeem (het O.S. of de programmeertaal)<br />

moet maar zorg<strong>en</strong> dat het goed gaat.<br />

• Dus:<br />

– <strong>en</strong>ter_crit(section_id);<br />

– leave_crit(section_id);<br />

• Systeem gebruikt<br />

– Software met spin-lock <strong>en</strong>/of<br />

– Hardware ondersteuning<br />

College OS 2010 – 2011 17


HW ondersteuning: Test-and-set instructie<br />

Atomaire machine instructie (ook op SMP)<br />

TAS address<br />

– reserveert bus,<br />

leest van address,<br />

zet status bit voor nul/niet nul,<br />

schrijft 1 naar address,<br />

geeft bus vrij<br />

– Werkt ook op shared-memory multi-processor<br />

system<strong>en</strong><br />

– Gebruik (pseudo-assembler):<br />

try_address: TAS address<br />

BNZ try_address # branch if not zero<br />

critical section # if (*address == 0)<br />

CLR address # clear address<br />

College OS 2010 – 2011 18


• TAS mag in user code.<br />

Test-and-set 2<br />

• Maar is ook e<strong>en</strong> “spin-lock”, dus o.a. problem<strong>en</strong> met<br />

prioriteit<strong>en</strong> mogelijk.<br />

• Combineer dan b.v. met uitzett<strong>en</strong> interrupts. Pseudocode:<br />

while (TRUE) {<br />

interrupts off;<br />

if (not testAndSet(address)) break;<br />

interrupts on; }<br />

Critical section;<br />

*address = 0;<br />

interrupts on;<br />

• Dan ook alle<strong>en</strong> kleine kritieke secties <strong>en</strong> vertrouwde<br />

routines<br />

College OS 2010 – 2011 19


Compare-and-swap<br />

• TAS schrijft altijd - duur voor SMP cache<br />

• Compare-and-swap instructie CS in de<br />

instructieset IBM 370 <strong>en</strong> Motorola 68000.<br />

(Boek Mil<strong>en</strong>kovic)<br />

– CS is e<strong>en</strong> ondeelbare instructie (ook op e<strong>en</strong> multiprocessor<br />

kan ook e<strong>en</strong> andere processor niet<br />

tuss<strong>en</strong>door aan het geheug<strong>en</strong> zitt<strong>en</strong>)<br />

– “Optimistische” afscherming<br />

• Ga kritieke sectie in<br />

• Test net voor terugschrijv<strong>en</strong> kritieke variabele<br />

– Schrijft alle<strong>en</strong> bij succes<br />

College OS 2010 – 2011 20


Werking CS instructie<br />

– Globvar: variabele in geheug<strong>en</strong><br />

– Oldreg: kopie van “oude” Globvar in register.<br />

– Newreg: nieuwe waarde voor Globvar in register.<br />

Vergelijk Oldreg met Globvar<br />

Zet de waard<strong>en</strong> in het Condition Code register<br />

Als (Oldreg == Globvar)<br />

dan Globvar = Newreg /* succes! */<br />

anders Oldreg = Globvar /* opnieuw */<br />

– Er is ook e<strong>en</strong> variant die eerst twee waard<strong>en</strong><br />

vergelijkt (robuuster).<br />

College OS 2010 – 2011 21


Ev<strong>en</strong>t counters<br />

• Object met unsigned integer waarde <strong>en</strong> 3 method<strong>en</strong>:<br />

unsigned int advance();<br />

– Increm<strong>en</strong>teer waarde atomair <strong>en</strong> geef oude waarde terug<br />

(combineert eig<strong>en</strong>lijk Ev<strong>en</strong>t Counter <strong>en</strong> Sequ<strong>en</strong>cer)<br />

unsigned int read();<br />

– Geef waarde terug (kan inmiddels alweer verhoogd zijn)<br />

unsigned int wait(unsigned int value);<br />

– Blokkeer tot minimaal “value” is bereikt (kan inmiddels<br />

alweer verhoogd zijn)<br />

College OS 2010 – 2011 22


Gezam<strong>en</strong>lijk<br />

Afscherming met ev<strong>en</strong>t counter<br />

Ev<strong>en</strong>tCounter <strong>en</strong>ter, leave; // start op 0<br />

// Per proces/thread<br />

unsigned int number;<br />

number = <strong>en</strong>ter.advance(); // vraag nummer<br />

leave.wait(number); // tel vertrek<br />

// Kritieke sectie<br />

leave.advance(); // meld vertrek<br />

College OS 2010 – 2011 23


Advance met Compare & Swap<br />

• Pseudo-assembler:<br />

Advance: mov reg1, counterValue<br />

again: mov reg2, reg1<br />

inc reg2<br />

cs reg2, reg1, counterValue<br />

bne again<br />

push reg1 // returnwaarde<br />

• Interrupts kunn<strong>en</strong> gewoon aan blijv<strong>en</strong><br />

• Mag door user-code word<strong>en</strong> uitgevoerd<br />

• Hoe zit het hier met prioriteit<strong>en</strong>?<br />

College OS 2010 – 2011 24


Voor- <strong>en</strong> nadel<strong>en</strong> ev<strong>en</strong>t counter<br />

• “Wait” kan als system call zonder busy<br />

waiting word<strong>en</strong> geïmplem<strong>en</strong>teerd<br />

• Voor afscherming kritieke sectie twee<br />

counters nodig, plus hulpvariabele<br />

• Waarde kan erg groot word<strong>en</strong><br />

College OS 2010 – 2011 25


Semafor<strong>en</strong><br />

• Semafor<strong>en</strong> zijn object<strong>en</strong> met<br />

– E<strong>en</strong> niet-negatieve, heeltallige waarde<br />

– Twee method<strong>en</strong>:<br />

• P(sem) - indi<strong>en</strong> waarde van sem > 0, verlaag waarde met 1<br />

indi<strong>en</strong> waarde == 0, blokkeer taak<br />

• V(sem) - indi<strong>en</strong> er geblokkeerde tak<strong>en</strong> zijn, deblokkeer er één<br />

anders, verhoog waarde met 1<br />

– P heet ook wel: get_semaphore, take_semaphore, down, ….<br />

– V heet ook wel: give_semaphore, up, ….<br />

– NB. Je kan de waarde niet direct manipuler<strong>en</strong><br />

• Binaire semafor<strong>en</strong>: alle<strong>en</strong> waard<strong>en</strong> nul <strong>en</strong> één<br />

– E<strong>en</strong> tweede V() verhoogt niet verder.<br />

College OS 2010 – 2011 26


• Oplossing 1:<br />

Semafor<strong>en</strong> voor afscherming<br />

– Maak 1 semafoor aan “mutex”, beschikbaar voor<br />

alle tak<strong>en</strong>.<br />

– Gebruik:<br />

P(mutex);<br />

/* Kritieke sectie */<br />

V(mutex);<br />

– Gevolg: veel nodeloos wacht<strong>en</strong>.<br />

College OS 2010 – 2011 27


E<strong>en</strong> te fijnmazige afscherming<br />

• Bij elke gedeelde variabele e<strong>en</strong> semafoor:<br />

– Gebruik b.v. (A <strong>en</strong> B gedeeld)<br />

P(sem_A);<br />

temp = A;<br />

P(sem_B);<br />

A = B;<br />

V(sem_A);<br />

B = temp;<br />

V(sem_B);<br />

– Bewerkelijk; kans op deadlock<br />

• Het beste: e<strong>en</strong> semafoor voor e<strong>en</strong> bij elkaar<br />

hor<strong>en</strong>de groep variabel<strong>en</strong>.<br />

College OS 2010 – 2011 28


• Taak afhankelijk van<br />

andere.<br />

• Preced<strong>en</strong>tiegraaf:<br />

Taak A<br />

Taak B<br />

Taak E<br />

Synchronisatie<br />

Taak C<br />

Taak D<br />

Taak F<br />

TaakA(){ ... ; V(AB); V(AC);}<br />

TaakB(){ P(AB); ... ; V(BD);<br />

V(BE);}<br />

TaakC(){ P(AC); ... ; V(CD);}<br />

TaakD(){ P(BD); P(CD) ; ... ;<br />

V(DF);}<br />

TaakE(){ P(BE); ... ; V(EF);}<br />

TaakF(){ P(EF); P(DF); ... ;}<br />

College OS 2010 – 2011 29


Tell<strong>en</strong>de semafoor - e<strong>en</strong> toepassing<br />

• Ringbuffer<br />

• Produc<strong>en</strong>t vraagt e<strong>en</strong> leeg<br />

vakje <strong>en</strong> maakt dat vol<br />

Producer() {<br />

while (1) {<br />

produce();<br />

empty.P();<br />

fill_buffer();<br />

full.V();<br />

}<br />

}<br />

• Werkt dit ook bij 4<br />

produc<strong>en</strong>t<strong>en</strong>?<br />

Produc<strong>en</strong>t<br />

L<br />

L<br />

College OS 2010 – 2011 30<br />

L<br />

L<br />

V<br />

L V<br />

V<br />

V<br />

Consum<strong>en</strong>t


Oplossing met meer produc<strong>en</strong>t<strong>en</strong><br />

• Produc<strong>en</strong>t<strong>en</strong> moet<strong>en</strong><br />

– het onderling e<strong>en</strong>s zijn<br />

over de te schrijv<strong>en</strong><br />

buffer.<br />

– op juiste volgorde<br />

full.V() uitvoer<strong>en</strong><br />

(waarom)?<br />

• Tell<strong>en</strong>de, of algem<strong>en</strong>e<br />

semafor<strong>en</strong>:<br />

– empty <strong>en</strong> full<br />

• Binaire semafoor of<br />

“mutex”:<br />

– writing<br />

Producer() {<br />

}<br />

while (1) {<br />

}<br />

produce();<br />

empty.P();<br />

writing.P();<br />

fill_buffer();<br />

writing.V();<br />

full.V();<br />

College OS 2010 – 2011 31


Maak e<strong>en</strong> tell<strong>en</strong>de semafoor met binaire<br />

(oplossing is niet goed - waarom?)<br />

class countingSemaphore<br />

{<br />

procedure Wait();<br />

begin<br />

mutex.WaitB();<br />

s = s - 1;<br />

if s < 0 th<strong>en</strong> begin<br />

mutex.SignalB();<br />

delay.WaitB()<br />

<strong>en</strong>d<br />

else<br />

mutex.SignalB()<br />

<strong>en</strong>d;<br />

procedure Signal();<br />

begin<br />

mutex.WaitB();<br />

s = s + 1;<br />

if s


Maak e<strong>en</strong> tell<strong>en</strong>de semafoor met binaire<br />

(de goede oplossing - waarom?)<br />

procedure Wait(var s<br />

semaphore);<br />

<strong>en</strong>d;<br />

begin<br />

mutex.WaitB();<br />

s = s - 1;<br />

if s < 0 th<strong>en</strong> begin<br />

mutex.SignalB();<br />

delay.WaitB()<br />

<strong>en</strong>d;<br />

mutex.SignalB();<br />

procedure Signal(var s<br />

semaphore);<br />

<strong>en</strong>d;<br />

begin<br />

mutex.WaitB();<br />

s = s + 1;<br />

if s


Problem<strong>en</strong> met semafor<strong>en</strong><br />

• Programmeur blijft verantwoordelijk voor<br />

correcte afscherming<br />

– Kan die omzeil<strong>en</strong><br />

– Kan fout<strong>en</strong> mak<strong>en</strong><br />

• E<strong>en</strong> taak die crasht in de kritieke sectie houdt<br />

die bezet<br />

• Wacht<strong>en</strong> op twee of meer <strong>condities</strong> tegelijk is<br />

lastig.<br />

College OS 2010 – 2011 34


• Niet te omzeil<strong>en</strong><br />

Meer eis<strong>en</strong> aan afscherming<br />

– Impliceert data-hiding<br />

• E<strong>en</strong>voudig in het gebruik<br />

– Gebruiker moet zich er nauwelijks van bewust zijn<br />

College OS 2010 – 2011 35


“Monitors”<br />

• Als taalelem<strong>en</strong>t o.a. in “Concurr<strong>en</strong>t Pascal”<br />

<strong>en</strong> in JAVA<br />

• Als concept overal toepasbaar<br />

• E<strong>en</strong> monitor is e<strong>en</strong> module waarin niet meer<br />

dan één taak tegelijk actief kan zijn<br />

• Binn<strong>en</strong> e<strong>en</strong> monitor ook <strong>condities</strong> of “ev<strong>en</strong>ts”<br />

waarop kan word<strong>en</strong> gewacht<br />

College OS 2010 – 2011 36


– Binn<strong>en</strong> e<strong>en</strong> monitor<br />

kan slechts één proces<br />

tegelijk actief zijn<br />

– Tijdelijk verlat<strong>en</strong> via<br />

"wait(condition)"<br />

– Weer terug na<br />

"signal(condition)"<br />

– Wat gebeurt er met<br />

het proces dat "signal"<br />

doet?<br />

Met e<strong>en</strong> plaatje<br />

Uitgang<br />

Toegang<br />

Operaties<br />

Ev<strong>en</strong>ts<br />

één proces tegelijk<br />

Data<br />

Initialisatie<br />

College OS 2010 – 2011 37


Bouw e<strong>en</strong> semafoor met e<strong>en</strong> monitor<br />

monitor semafoor {<br />

}<br />

static unsigned int waarde = 0;<br />

static condition V_called;<br />

void P(){<br />

}<br />

if (waarde == 0) wait(V_called);<br />

waarde--;<br />

void V(){<br />

}<br />

waarde++;<br />

signal(V_called);<br />

College OS 2010 – 2011 38


monitor buffer {<br />

static int full = 0;<br />

static int empty = Nbuf;<br />

static condition produced;<br />

static condition consumed;<br />

static int i_prod = 0;<br />

static int i_cons = 0;<br />

datum buf[Nbuf];<br />

void get(datum *out){<br />

}<br />

if (full == 0)<br />

wait(produced); ....<br />

Bufferbeheer<br />

}<br />

void put(datum in){<br />

}<br />

if (empty == 0)<br />

wait(consumed);<br />

empty--; full++;<br />

buf[i_prod] = in;<br />

i_prod = (i_prod + 1) %<br />

Nbuf;<br />

signal(produced);<br />

College OS 2010 – 2011 39


public class buffer {<br />

int store[];<br />

int filled;<br />

int empty;<br />

int readFrom;<br />

int writeTo;<br />

buffer (int size){<br />

empty = size;<br />

filled = 0;<br />

store = new int[size];<br />

readFrom = 0;<br />

writeTo = 0;<br />

}<br />

En nu in Java<br />

public synchronized void write(int value)<br />

{<br />

while (empty == 0){<br />

try { wait(); }<br />

catch(InterruptedException e) {<br />

System.err.println(e.toString());<br />

}<br />

}<br />

store[writeTo] = value;<br />

writeTo++;<br />

if (writeTo == (empty + filled))<br />

writeTo = 0;<br />

filled++;<br />

empty--;<br />

notifyAll();<br />

}<br />

College OS 2010 – 2011 40


Read in Java<br />

public synchronized int read(){<br />

int value;<br />

while (filled == 0) {<br />

try {<br />

wait(); } catch(InterruptedException e) {<br />

System.err.println(e.toString()); }<br />

}<br />

value = store[readFrom];<br />

readFrom++;<br />

if (readFrom == (empty + filled)) readFrom = 0;<br />

filled--;<br />

empty++;<br />

notifyAll();<br />

return value;<br />

}<br />

}<br />

College OS 2010 – 2011 41


Semantiek wait/signal<br />

• Als er ge<strong>en</strong> taak wacht, gaat “signal” verlor<strong>en</strong>.<br />

• Keuze:<br />

– signal bevrijdt 1 wacht<strong>en</strong>de<br />

– of bevrijdt alle wacht<strong>en</strong>d<strong>en</strong> (NotifyAll() in Java).<br />

• Na signal één taak tegelijk actief in monitor. Welke?<br />

– Taak „S‟ die signal deed<br />

• „Wait‟ conditie kan weer ongeldig word<strong>en</strong>.<br />

– Taak „W‟ die wait deed<br />

• Wat gebeurt er met taak „S‟; wanneer mag die weer?<br />

Is de toestand dan nog juist voor hem?<br />

– Veel gebruikt: signal alle<strong>en</strong> als laatste opdracht in<br />

monitor.<br />

• Is minder krachtig.<br />

College OS 2010 – 2011 42


Readers/writers<br />

• N lezers of één schrijver<br />

• Lezers voorrang, of schrijvers, of afwissel<strong>en</strong><br />

• Afwissel<strong>en</strong> – keus in voorbeeld:<br />

– Als er wordt gelez<strong>en</strong> <strong>en</strong> e<strong>en</strong> schrijver wacht, laat<br />

ge<strong>en</strong> nieuwe lezers toe<br />

– Als e<strong>en</strong> schrijver klaar is, laat eerst alle wacht<strong>en</strong>de<br />

lezers toe<br />

• Functies:<br />

– startRead()<br />

– <strong>en</strong>dRead()<br />

– startWrite()<br />

– <strong>en</strong>dWrite()<br />

College OS 2010 – 2011 43


monitor ReadersAndWriters {<br />

static int Readers = 0;<br />

static int SomeoneIsWriting = 0;<br />

static condition ReadingAllowed,<br />

WritingAllowed;<br />

startRead () {<br />

if (SomeoneIsWriting ||<br />

Readers++;<br />

Readers/writers monitor<br />

queue(WritingAllowed))<br />

wait(ReadingAllowed);<br />

signal(ReadingAllowed);<br />

}<br />

<strong>en</strong>dRead () {<br />

Readers--;<br />

if (Readers == 0)<br />

signal(WritingAllowed);<br />

}<br />

}<br />

startWrite () {<br />

}<br />

if ((Readers > 0) ||<br />

<strong>en</strong>dWrite () {<br />

}<br />

SomeoneIsWriting)<br />

wait(WritingAllowed);<br />

SomeoneIsWriting = 1;<br />

SomeoneIsWriting = 0;<br />

if (queue(ReadingAllowed))<br />

signal(ReadingAllowed);<br />

else<br />

signal(WritingAllowed);<br />

College OS 2010 – 2011 44


Readers/writers met semafor<strong>en</strong><br />

startRead() <strong>en</strong>dRead() startWrite()<br />

{ { {<br />

}<br />

down(reader); down(mutex); down(reader);<br />

down(mutex); readers--; down(writer);<br />

if (readers == 0) if (readers == 0) }<br />

{ {<br />

down(writer); up(writer); <strong>en</strong>dWrite()<br />

} } {<br />

readers++; up(mutex); up(writer);<br />

up(reader); } up(reader);<br />

up(mutex); }<br />

Kijk goed hoe het werkt. Wie krijgt voorrang? Wat verandert er als ik de eerste twee down()<br />

statem<strong>en</strong>ts in startRead() omwissel? En in startWrite()?<br />

College OS 2010 – 2011 45


Conclusie<br />

Monitors<br />

• Toegang strikt beperkt tot één taak<br />

– B.v. niet zo geschikt voor readers/writers<br />

• Nette, modulaire structuur<br />

– Wel neiging om e<strong>en</strong> beetje veel af te scherm<strong>en</strong><br />

– Niet erg flexibel toepasbaar<br />

• Geschikt voor shared-memory multiprocessor<strong>en</strong><br />

– Niet zondermeer voor netwerk<strong>en</strong><br />

College OS 2010 – 2011 46


Inter-proces communicatie<br />

IPC


Uitwisseling van informatie<br />

• Alle mechanism<strong>en</strong> tot nu toe voor shared<br />

memory<br />

– bruikbaar voor afscherming <strong>en</strong> synchronisatie<br />

– informatie-uitwisseling via shared memory<br />

• Informatie-uitwisseling met boodschapp<strong>en</strong><br />

– s<strong>en</strong>d(&message, to_desitination)<br />

– receive(&message, from_s<strong>en</strong>der)<br />

• Wat zijn de eig<strong>en</strong>schapp<strong>en</strong> van s<strong>en</strong>d <strong>en</strong><br />

receive?<br />

College OS 2010 – 2011 48


• Synchroon:<br />

Synchroon / asynchroon<br />

– Ontvanger <strong>en</strong> afz<strong>en</strong>der blokker<strong>en</strong> totdat boodschap<br />

is uitgewisseld.<br />

• Asynchoon: alle andere mogelijkhed<strong>en</strong>, b.v.<br />

– Gebufferd of<br />

– Non-blocking<br />

College OS 2010 – 2011 49


Gebufferde communicatie<br />

• Afz<strong>en</strong>der plaatst boodschap in buffer <strong>en</strong> gaat<br />

mete<strong>en</strong> door<br />

• Ontvanger wacht tot er e<strong>en</strong> boodschap is<br />

• Eén, meerdere of onbeperkt veel buffers<br />

• Bij volle buffers<br />

– foutmelding aan afz<strong>en</strong>der <strong>en</strong> oudste of nieuwste<br />

boodschap verlor<strong>en</strong>, of<br />

– afz<strong>en</strong>der blokkeert tot er e<strong>en</strong> buffer vrij komt<br />

• Kost extra kopieerslag(<strong>en</strong>)<br />

College OS 2010 – 2011 50


Non-blocking<br />

• Afz<strong>en</strong>der verzoekt systeem boodschap te verstur<strong>en</strong><br />

– systeem neemt adres boodschap over<br />

– afz<strong>en</strong>der kan mete<strong>en</strong> verder<br />

• maar mag niet aan boodschap zitt<strong>en</strong><br />

– systeem zorgt voor verz<strong>en</strong>ding<br />

– systeem meldt als boodschap is overg<strong>en</strong>om<strong>en</strong><br />

• signaal of<br />

• “polling”<br />

• Ontvangst gaat analoog<br />

• Blocking receive kan bij non-blocking s<strong>en</strong>d <strong>en</strong> v.v.<br />

• Non-blocking kan ook gebufferd<br />

College OS 2010 – 2011 51


UNIX read/write<br />

• int read(int fd, void *buf, size_t nbyte)<br />

– geeft feitelijk gelez<strong>en</strong> aantal bytes terug<br />

– leest in principe nbyte bytes, maar kan o.a. van e<strong>en</strong><br />

socket of pipe of bij EOF ook minder teruggev<strong>en</strong><br />

– O_NDELAY <strong>en</strong> O_NONBLOCK staan ook toe dat 0<br />

bytes word<strong>en</strong> gelez<strong>en</strong><br />

• int write(int fd, void *buf, size_t nbyte)<br />

– geeft feitelijk geschrev<strong>en</strong> aantal bytes terug<br />

– schrijft in principe nbyte bytes<br />

– O_NDELAY <strong>en</strong> O_NONBLOCK staan ook toe dat er<br />

minder word<strong>en</strong> geschrev<strong>en</strong><br />

• Zie man pages…...<br />

College OS 2010 – 2011 52


Adressering<br />

• Adres teg<strong>en</strong>partij moet bek<strong>en</strong>d zijn<br />

– verbinding is eerder opgezet<br />

• B.v. UNIX pipe<br />

– “well-known address”<br />

• B.v. adres van ftp server op e<strong>en</strong> bepaalde machine<br />

– door bemiddeling verkreg<strong>en</strong> adres<br />

• B.v. e<strong>en</strong> in e<strong>en</strong> http docum<strong>en</strong>t gevond<strong>en</strong> e-mail adres<br />

• Bemiddelaar heeft i.h.a. e<strong>en</strong> well-known address<br />

– verbinding bek<strong>en</strong>d, teg<strong>en</strong>partij niet<br />

• B.v. mailbox<br />

– beperkte broadcast<br />

• B.v. gebruikt op LAN<br />

College OS 2010 – 2011 53


Synchroon<br />

Asynchroon<br />

E<strong>en</strong> heel onvolledige indeling<br />

Afz<strong>en</strong>der specificeert ontvanger<br />

Wel Niet<br />

Ontvanger specificeert<br />

afz<strong>en</strong>der<br />

Wel Niet<br />

Hand<strong>en</strong><br />

schudd<strong>en</strong><br />

Telefoon<br />

Ontvanger specificeert<br />

afz<strong>en</strong>der<br />

Wel Niet<br />

UNIX pipe Brief WWW pagina Brief in fles<br />

e-mail<br />

Radio<br />

Sommige<br />

vergadering<strong>en</strong><br />

Reclame<br />

drukwerk<br />

College OS 2010 – 2011 54


UNIX pipe<br />

• Verbinding tuss<strong>en</strong> ouder <strong>en</strong> kind<br />

– Of tuss<strong>en</strong> verdere verwant<strong>en</strong> op e<strong>en</strong> machine<br />

• Nodig: twee integer file descriptors: int f_id[2];<br />

• Ouder roept eerst “pipe(f_id)” aan<br />

– Krijgt 2 file-ids terug (SUN Solaris). Wat wordt<br />

geschrev<strong>en</strong> naar de e<strong>en</strong>, kan word<strong>en</strong> gelez<strong>en</strong> uit de<br />

ander.<br />

• Ouder roept vervolg<strong>en</strong>s “fork()” aan.<br />

– Ouder leest / schrijft b.v. f_id[0]<br />

– Kind leest / schrijft dan f_id[1]<br />

– E<strong>en</strong> bi-directionele verbinding!<br />

• Ouder <strong>en</strong> kind kunn<strong>en</strong> hun kant weer doorgev<strong>en</strong><br />

College OS 2010 – 2011 55


F_id[0]<br />

F_id[1]<br />

Na pipe()<br />

Solaris pipes<br />

F_id[0]<br />

F_id[1]<br />

Na fork()<br />

F_id[1]<br />

F_id[0]<br />

F_id[0] F_id[1]<br />

Na close()<br />

College OS 2010 – 2011 56


LINUX <strong>en</strong> Posix<br />

• De pipe() functie werkt hetzelfde, maar de<br />

verbinding is uni-directioneel<br />

– Lez<strong>en</strong> uit f_id[0],<br />

– Schrijv<strong>en</strong> naar f_id[1];<br />

• Voor e<strong>en</strong> bi-directionele verbinding zijn dus<br />

twee aanroep<strong>en</strong> nodig.<br />

• Socketpair(PF_UNIX, SOCK_STREAM, 0, f_id)<br />

– werkt bijna hetzelfde als de Solaris pipe() functie<br />

College OS 2010 – 2011 57


F_id[0]<br />

F_id[1]<br />

Na pipe()<br />

LINUX <strong>en</strong> POSIX pipes<br />

F_id[0]<br />

F_id[1]<br />

Na fork()<br />

F_id[1]<br />

F_id[0]<br />

F_id[0] F_id[1]<br />

Na close()<br />

College OS 2010 – 2011 58


UNIX shells <strong>en</strong> pipes<br />

sh> ls * | grep o1 | less<br />

shell maakt pipe aan: f_id[0] <strong>en</strong> f_id[1]<br />

shell forkt kind1 af<br />

kind1 verbindt stdout met f_id[1], sluit f_id[0]<br />

kind1 start ls<br />

shell sluit f_id[1]; maakt pipe aan: f_id[2] <strong>en</strong> f_id[3]<br />

shell forkt kind2 af<br />

kind2 verbindt stdin met f_id[0], stdout met f_id[3], sluit<br />

f_id[2]<br />

kind2 start grep<br />

shell sluit f_id[0], f_id[3]; forkt kind3 af<br />

kind3 verbindt stdin met f_id[2]<br />

kind3 start less<br />

shell sluit f_id[2], wacht<br />

College OS 2010 – 2011 59


Internet sockets<br />

• Socket: e<strong>en</strong> eindpunt voor communicatie<br />

• Opzet asymmetrisch: server <strong>en</strong> cliënt<br />

• Server maakt socket aan; bindt deze aan poortnummer<br />

<strong>en</strong> protocol (TCP of UDP).<br />

– Volledig adres: machine-adres + poortnummer<br />

– Well-known adresses: zie /etc/services<br />

• Cli<strong>en</strong>t maakt socket aan; zoekt verbinding met poort<br />

op machine.<br />

• Bij succes:<br />

– Server krijgt nieuwe file-id voor verbinding met deze<br />

cliënt<br />

– Poort + machine beschikbaar voor volg<strong>en</strong>d contact<br />

– Gebruik TCP socket verder als bij pipe<br />

College OS 2010 – 2011 60


node nr. 146.50.7.64<br />

server process<br />

socket()<br />

bind()<br />

s0<br />

s0<br />

Internet sockets in e<strong>en</strong> plaatje<br />

port 2345<br />

s<br />

node nr. 146.50.5.23<br />

cli<strong>en</strong>t process<br />

socket()<br />

list<strong>en</strong>()<br />

loop: {<br />

}<br />

....<br />

accept()<br />

....<br />

s0<br />

s0<br />

s1<br />

s0<br />

s0 s2<br />

port 2345<br />

port 2345<br />

port 2345<br />

connect()<br />

College OS 2010 – 2011 61<br />

s<br />

s<br />

s<br />

s


Sockets, vervolg<br />

• Met UDP is ook e<strong>en</strong> datagram service<br />

mogelijk, adressering per pakket<br />

• Met elke socket verbinding is e<strong>en</strong><br />

poortnummer geassocieerd, meestal<br />

automatisch toegewez<strong>en</strong><br />

College OS 2010 – 2011 62


Van asynchroon naar synchroon <strong>en</strong> v.v.<br />

Partij A<br />

S<strong>en</strong>d(&message, destination)<br />

Receive(&ack, destination)<br />

Partij B<br />

Receive(&message, s<strong>en</strong>der)<br />

S<strong>en</strong>d(&ack, s<strong>en</strong>der)<br />

• Maar B weet niet of bevestiging bij A is aangekom<strong>en</strong>.<br />

• Voor synchroon naar asynchroon is e<strong>en</strong> derde partij<br />

nodig die als buffer kan optred<strong>en</strong> + nog wat speciale<br />

voorzi<strong>en</strong>ing<strong>en</strong>.<br />

College OS 2010 – 2011 63


Gebruik message passing<br />

• Overdracht informatie: duidelijk<br />

• Synchronisatie: duidelijk<br />

• Afscherming gegev<strong>en</strong>s <strong>en</strong> resources:<br />

– Gebruik server proces dat gegev<strong>en</strong>s <strong>en</strong>/of<br />

resources beheert.<br />

– Cliënt<strong>en</strong> stur<strong>en</strong> verzoek aan server, die operaties<br />

voor hun uitvoert <strong>en</strong> resultaat terugstuurt.<br />

• Cliënt/server system<strong>en</strong> algeme<strong>en</strong>:<br />

– B.v. file server, print server<br />

– Servers vaak “multi-threaded”<br />

• Echte gedistribueerde system<strong>en</strong> word<strong>en</strong><br />

mogelijk<br />

College OS 2010 – 2011 64


Hoofd thread:<br />

• ontvang verzoek<br />

• start service thread<br />

Multi-threaded server<br />

– geef verzoek aan service<br />

thread<br />

• ga terug naar “ontvang<br />

verzoek”<br />

Service thread<br />

• handel verzoek af<br />

• communiceer resultaat<br />

met cliënt<br />

• beëindig thread<br />

• Zo hoeft e<strong>en</strong> volg<strong>en</strong>de service-aanvraag niet op<br />

afhandeling vorige te wacht<strong>en</strong>.<br />

• Aanmak<strong>en</strong> threads is goedkoop.<br />

• Threads synchroniser<strong>en</strong> onderling met semafor<strong>en</strong> of<br />

monitors..<br />

College OS 2010 – 2011 65


Cliënt proces<br />

procedure aanroep<br />

De remote procedure call<br />

“Marshalling”<br />

Server proces<br />

Call-back routine<br />

Stub routine<br />

Server stub<br />

Pak data in/uit<br />

Pak data in/uit<br />

S<strong>en</strong>d Receive S<strong>en</strong>d Receive<br />

• Overstur<strong>en</strong> data niet triviaal:<br />

– Formaat conversie bij e<strong>en</strong>voudige types<br />

– Verschill<strong>en</strong> in bereik<br />

– Pointers niet meer geldig - problem<strong>en</strong> met<br />

bom<strong>en</strong> etc.<br />

College OS 2010 – 2011 66


Marshalling Problem<strong>en</strong><br />

• Data format<strong>en</strong>:<br />

– Big-<strong>en</strong>dian vs. little-<strong>en</strong>dian<br />

– Char, int, float repres<strong>en</strong>tatieverschill<strong>en</strong><br />

• Verschill<strong>en</strong> in bereik<br />

– Alignm<strong>en</strong>t eis<strong>en</strong> bij structs<br />

• Bouw e<strong>en</strong> struct b.v. als<br />

struct PORTABLE {<br />

double a;<br />

long l;<br />

short s, dummy;<br />

char c[3], filler[5]; }<br />

– Pointers hebb<strong>en</strong> op de andere machine ge<strong>en</strong><br />

betek<strong>en</strong>is<br />

• Serialiseer bom<strong>en</strong> e.d.<br />

College OS 2010 – 2011 67


Message passing fout<strong>en</strong><br />

• Failures:<br />

(Voor alle message passing techniek<strong>en</strong>, maar<br />

a fortiori voor RPC omdat die transparant<br />

zoud<strong>en</strong> moet<strong>en</strong> zijn)<br />

– Kan server niet vind<strong>en</strong><br />

– Verlor<strong>en</strong> boodschapp<strong>en</strong>:<br />

• Request boodschap<br />

• Reply<br />

– Server crash na ontvangst request<br />

– Cliënt crash na verstur<strong>en</strong> request<br />

College OS 2010 – 2011 68


• Hardware:<br />

Gedistribueerde system<strong>en</strong><br />

– “Losse” nodes verbond<strong>en</strong> door e<strong>en</strong> netwerk<br />

• Lokaal … wereldwijd<br />

– Mogelijk inhomoge<strong>en</strong><br />

– Nodes kunn<strong>en</strong> shared-memory system<strong>en</strong> zijn<br />

• Software<br />

– E<strong>en</strong> gedistribueerd OS<br />

• B.v. Amoeba<br />

– Verschill<strong>en</strong>de OS met “homog<strong>en</strong>isatie laag”<br />

• B.v. Java, PVM<br />

College OS 2010 – 2011 69


Structuur van het O.S.<br />

• E<strong>en</strong> paar O.S. tak<strong>en</strong> ligg<strong>en</strong> onder alle process<strong>en</strong><br />

– Met name dat deel dat process-switching verzorgt<br />

• Of, de rest van het O.S. draait<br />

– Geheel als aparte kernel. Niet als proces.<br />

– In kernel mode als onderdeel van elk proces (o.a. UNIX).<br />

– Als e<strong>en</strong> aantal aparte process<strong>en</strong><br />

• UNIX:<br />

Proces 1<br />

O.S.<br />

Functies<br />

Proces 2<br />

O.S.<br />

Functies<br />

Proces 3<br />

O.S.<br />

Functies<br />

Process switching code<br />

Proces 4<br />

O.S.<br />

Functies<br />

User mode<br />

Kernel mode<br />

College OS 2010 – 2011 70


Microkernel<br />

• Amoeba (Tan<strong>en</strong>baum) heeft microkernel structuur<br />

– Microkernel ondersteunt<br />

User<br />

process<br />

• Process switching<br />

• Interprocess communication (IPC) op basis van RPC<br />

• Distributie<br />

User<br />

process<br />

M.M.<br />

process<br />

User<br />

process<br />

File<br />

server<br />

process<br />

Microkernel Microkernel<br />

M.M.<br />

process<br />

College OS 2010 – 2011 71

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!