Prezentace se nahrává, počkejte prosím

Prezentace se nahrává, počkejte prosím

Operační systémy Přednášky pro výuku předmětu Operační systémy Ing. Antonín Vaněk, CSc. DFJP, Univerzita Pardubice září 2003.

Podobné prezentace


Prezentace na téma: "Operační systémy Přednášky pro výuku předmětu Operační systémy Ing. Antonín Vaněk, CSc. DFJP, Univerzita Pardubice září 2003."— Transkript prezentace:

1 Operační systémy Přednášky pro výuku předmětu Operační systémy Ing. Antonín Vaněk, CSc. DFJP, Univerzita Pardubice září 2003

2 Kapitola 5 Konkurence procesů: vzájemné vylučování a synchronizace

3 Konkurence  procesy si konkurují při:  sdílení prostředků  alokaci času procesoru  komunikaci procesů  synchronizaci více procesů

4 Interakce procesů  procesy nevědí jeden o druhém  interakce neexistuje  procesy o sobě vědí jen nepřímo  interakci zprostředkuje OS nebo jiný program  procesy o sobě vědí přímo  je možná přímá interakce

5 Zájmová sféra OS  sledování aktivity procesů  alokace a dealokace prostředků  čas procesoru  paměť  I/O zařízení  soubory  ochrana dat a prostředků výsledek procesu nesmí záviset na rychlosti provádění... sdílí s ostatními procesy čas procesoru

6 Soutěžení procesů o prostředky  provádění jednoho procesu může ovlivnit chování soupeřících procesů  pokud přístup k jednomu prostředku požaduje více procesů současně, lze prostředek přidělit jen jednomu z nich  ostatní procesy musí čekat !  nelze vždy zaručit, že blokovaný proces získá přístup k prostředku v budoucnosti  takový proces nikdy neskončí, bude bez omezení čekat !

7 Problémy s konkurencí  pokud přístup ke sdíleným prostředkům není řízen, může dojít k porušení konzistence dat  výsledek akcí prováděných procesy může být závislý na pořadí, v jakém procesy dostanou přidělen procesor  přístup ke sdíleným prostředkům je nutno řídit ! To je nepřípustné!

8 Příklad  procesy P1 a P2 mají přístup ke stejné proměnné a a provádějí stejnou proceduru echo  procesy mohou být kdykoliv (a tedy kdekoliv) přerušeny  pokud je P1 po provedení operace vstupu přerušen, pak se provede P2 a nakonec se dokončí P1... ... proces P1 vypíše znak, načtený procesem P2 !! static char a; void echo() { cin >> a; cout << a; }

9 Problémy s řízením přístupu  vzájemné vylučování (Mutual Exclusion)  v každém okamžiku smí mít přistup k prostředku pouze jeden proces  smrtící objetí (Deadlock)  procesy vzájemně čekají na uvolnění prostředků, přidělených jiným procesům  vyhladovění (Starvation)  proces nemůže získat přístup k požadovanému prostředku v důsledku obsazení prostředku jinými procesy

10 Kooperace procesů sdílením  procesy používají a mění sdílená data  sdílené proměnné, soubory, databáze...  v daném čase může data měnit pouze jeden proces  např. textový soubor nesmí být otevřen pro zápis více editory současně  k zajištění integrity dat se používají kritické sekce

11 Kooperace procesů komunikací  vzájemná komunikace procesům umožňuje synchronizovat (koordinovat) různé aktivity  může nastat smrtící objetí  každý proces čeká na zprávu od některého jiného procesu ... žádný z procesů nemůže pokračovat  může nastat vyhladovění  dva procesy si stále vyměňují zprávy, zatímco jiný proces čeká na zprávu ... nikdy se jí nedočká

12 Kritická sekce  proces je ve (své) kritické sekci (pro daný sdílený prostředek), jestliže provádí část programu, manipulující s (tímto) sdíleným prostředkem  provádění kritické sekce musí být vzájemně výlučné (mutually exclusive)  to platí i pro multiprocesorové prostředí  každý proces musí žádat o povolení ke vstupu do kritické sekce ! v každém okamžiku smí být v kritické sekci (pro daný prostředek) pouze jeden proces

13 Obecná struktura procesu  část programu, implementující protokol povolení přístupu, nazýváme vstupní sekce  po vlastní kritické sekci (tj. úseku, kde dochází k vlastní manipulaci se sdíleným prostředkem) může následovat výstupní sekce  zbytek kódu se označuje jako zbytková sekce repeat entry section critical section exit section remainder section forever

14 Rámec pro řešení  procesy se provádějí nenulovou rychlostí  nedělají se žádné zvláštní předpoklady o relativní rychlosti procesů  může být použito i více procesorů, ale hardware paměti nesmí umožňovat současný přístup procesorů k jednomu paměťovému místu  nedělají se žádné zvláštní předpoklady o prokládaném provádění  stačí specifikovat vstupní a výstupní sekci

15 Požadované vlastnosti  vzájemné vylučování (Mutual Exclusion)  v kterémkoliv okamžiku může být v kritické sekci nejvýše jeden proces  pokrok v přidělování  pokud žádný proces není v kritické sekci a některé procesy tam chtějí vstoupit, na rozhodování o tom, který proces dostane povolení, se mohou podílet pouze procesy, které se nenacházejí ve zbytkové sekci  toto rozhodování se musí uskutečnit v konečném čase  omezené čekání  poté, co proces požádal o přístup, smí před ním získat přístup pouze omezený počet procesů  jinak by hrozilo vyhladovění

16 Typy řešení  SW řešení  algoritmy, jejichž korektnost nezávisí na dalších předpokladech (viz Rámec řešení)  HW řešení  využívá speciální instrukce procesoru  OS řešení  poskytuje programátorovi vhodné funkce a datové struktury

17 SW řešení: aktivní čekání Příklad:  svého šamana (kritickou sekci) může v daném čase navštívit pouze jediný eskymák (proces)  Igloo má malý vchod, takže dovnitř může vstoupit vždy jen jeden eskymák, aby si přečetl jméno napsané na tabuli  Pokud je na tabuli jeho jméno, může jít k šamanovi  Pokud je na tabuli napsáno jiné jméno, eskymák igloo opět opustí a čeká  Čas od času eskymák znovu vstoupí do igloo podívat se na tabuli

18 SW řešení  nejprve předpokládejme 2 procesy  algoritmy 1 a 2 jsou nesprávné  správný je algoritmus 3 (Petersonův)  potom řešení zobecníme pro n procesů  tzv. bakery algorithm  nejprve pro 2 procesy: P0 a P1 když uvažujeme proces Pi, proces Pj vždy představuje ostatní procesy (i != j)

19 Algoritmus 1  sdílená proměnná turn je inicializována (na 0 nebo 1) před provedením libovolného procesu Pi  kritická sekce CS procesu Pi se provádí, jestliže je turn = i  Pi aktivně čeká (busy waiting) pokud je Pj v kritické sekci: požadavek na vzájemné vylučování je splněn  požadavek pokroku není splněn, protože algoritmus vyžaduje přesné dodržení alternace kritických sekcí Process Pi: repeat while(turn!=i){}; CS turn:=j; RS forever

20 Algoritmus 1 - test  příklad:  předpokládejme, že P 0 má dlouhou zbytkovou sekci RS, P 1 krátkou  pokud je turn=0, P 0 vstoupí do CS a pak provádí dlouhou RS (turn=1)  zatím P 1 vstoupí do CS, provede krátkou RS (turn=0) a znovu se pokusí vstoupit do CS – ale požadavek je odmítnut ! P 1 musí čekat, dokud P 0 nedokončí RS

21  jedna booleovská proměnná flag pro každý proces: flag[0] a flag[1]  signalizace připravenosti ke vstupu do CS nastavením flag[i]:=true  požadavek na vzájemné vylučování je splněn  požadavek na pokrok splněn není  po sekvenci: P1: flag[1]:=true P0: flag[0]:=true budou oba procesy neomezeně čekat – máme deadlock Process Pi: repeat flag[i]:= true; while(flag[j]){}; CS flag[i]:= false; RS forever Algoritmus 2

22 Algoritmus 3 (Petersonův)  Inicializace: flag[0]:=flag[1]:=false turn:= 0 nebo 1  signalizace připravenosti ke vstupu do CS nastavením flag[i]:=true  Pokud se oba procesy pokusí vstoupit do CS současně, pouze jeden bude mít potřebnou hodnotu proměnné turn  výstupní sekce: specifikuje, že Pi nechce vstoupit do sekce CS Process Pi: repeat flag[i]:=true; turn:=j; do {} while (flag[j]and turn=j); CS flag[i]:=false; RS forever

23 Algoritmus 3 – analýza správnosti  požadavek na vzájemné vylučování je splněn  není možné, aby P 0 a P 1 byly oba v CS  nemůže nastat flag[0] = flag[1] = true a turn = i pro každý proces Pi  plnění požadavků na pokrok a omezenost čekání  Pi nemůže vstoupit do CS, pokud není současně flag[ j] = true a turn = j  pokud Pj není připraven ke vstupu do CS, je flag[ j] = false a Pi proto může vstoupit do CS

24  pokud Pj nastavil flag[ j]=true a je ve while(), pak je buďto turn=i nebo turn=j  je-li turn=i, pak Pi nevstupuje do CS (na řadě je Pj) ; pokud turn=j, pak Pj vstupuje do CS, ale při výstupu z CS nastaví flag[ j]=false a tím dovolí Pi vstoupit do CS  když Pj nastavuje flag[ j]=true, nastavil již turn=i  protože Pi po dobu čekání ve while() nemění nastavení turn, nemůže Pi vstoupit do CS, dokud nevstoupí do CS alespoň jednou také Pj (omezené čekání) Algoritmus 3 – analýza správnosti

25 Vliv chyb programu  pokud jsou splněna všechna 3 kriteria (vzájemné vylučování, pokrok a omezené čekání), pak je řešení odolné proti chybám ve zbytkové sekci (RS)  protože chyba v RS je vlastně totéž, co neomezeně dlouhá sekce RS  bohužel řešení nemůže zajistit odolnost proti chybám v kritické sekci (CS)  proces Pi, u kterého dojde k chybě v CS, signalizuje ostatním procesům tento fakt – Pi je pro tyto procesy stále v kritické sekci

26 Řešení pro n procesů t.zv. Bakery algoritmus  před vstupem do kritické sekce dostane každý proces číslo. Držitel nejmenšího čísla může vstoupit do CS  když Pi a Pj dostanou stejná čísla:  pokud je i<j, má přednost Pi, jinak Pj  ve výstupní sekci nastaví proces Pi přidělené číslo na 0

27 Bakery algoritmus  poznámky k zápisu:  (a,b) < (c,d) když a < c nebo když a = c a b < d  max(a 0,...a k ) je číslo b takové, že platí b >= a i pro i=0..k  sdílená data:  choosing: array[0..n-1] of boolean;  všechny prvky pole inicializovány na false  number: array[0..n-1] of integer;  všechny prvky pole inicializovány na 0  korektnost programu závisí na následujícím faktu:  jestliže je Pi v CS a Pk si právě vybral své číslo number[k] != 0, pak (number[i],i) < (number[k],k)  ale důkaz je poněkud složitý...

28 Process Pi: repeat choosing[i]:=true; number[i]:= max(number[0]..number[n-1])+1; choosing[i]:=false; for j:=0 to n-1 do { while (choosing[j]) {}; while (number[j]!=0 and (number[j],j)<(number[i],i)){}; } CS number[i]:=0; RS forever Bakery algoritmus

29 Nedostatky SW řešení  Procesy požadující přístup do kritické sekce jsou v aktivním čekání (busy waiting) a proto zbytečně spotřebovávají čas procesoru  pokud jsou kritické sekce dlouhé, může být efektivnější čekající procesy blokovat...

30 HW řešení  opírá se o některé základní principy:  proces běží v procesoru kontinuálně, dokud nevyvolá službu OS nebo není přerušen  k přerušení procesu může dojít pouze na hranicích instrukcí  mezi dokončením jedné a zahájením další instrukce  přístup k paměťovému místu obvykle vylučuje současný přístup ostatních procesů k tomuto místu

31 Zákaz přerušení  proces běží, dokud nevyvolá službu OS nebo není přerušen  u jednoprocesorového systému zákaz přerušení zaručuje vzájemné vylučování  u víceprocesorových systémů nezaručuje  jsou omezeny možnosti procesoru prokládat programy  zákaz přerušení může významně snížit efektivnost provádění programů  v době, kdy je některý proces v kritické sekci, nelze procesor přidělit jinému procesu  obecně nevhodné řešení  prodlužuje se doba latence systému  vadí tam, kde je požadována rychlá reakce (multimedia, RT systémy)

32 Process Pi: repeat disable interrupts CS enable interrupts RS forever Zákaz přerušení

33 Speciální instrukce  přístup k paměťovému místu obvykle vylučuje přístup ostatních procesů k tomuto místu  lze navrhnout instrukci procesoru, která provádí dvě akce (např. čtení a zápis) s jedním paměťovým místem jako atomickou (nedělitelnou) operaci  provedení takové instrukce nelze přerušit a proto zaručuje vzájemné vylučování  dokonce i při použití více procesorů  takovou instrukci lze velmi jednoduše použít pro řešení problému vzájemného vylučování ... ale pro řešení dalších problémů kritické sekce (pokrok, omezené čekání) je nutné použít složitější programové konstrukce

34 Instrukce test-and-set  jediná instrukce procesoru přečte příznak a současně ho nastaví  pokud byl příznak nastaven už před provedením instrukce, nové nastavení nic nezmění  kritická sekce je obsazena a proces proto musí čekat ... pokud ale příznak nastaven nebyl, může proces vstoupit do kritické sekce  instrukce je nepřerušitelná a proto nemůže dojít k chybnému vyhodnocení příznaku  lze použít u jedno- i víceprocesorových systémů  lze použít pro více kritických sekcí

35 Instrukce test-and-set  popis instrukce test-and-set v jazyce C++: bool testset(int& i) { if (i==0) { i=1; return true; } else { return false; }

36 Instrukce test-and-set  Nevýhody  jedná se o aktivní čekání, zabírající čas procesoru  může dojít k vyhladovění  když proces uvolní kritickou sekci, jako další získá povolení proces, který první provede instrukci  v systému může vzniknout deadlock  proces s nízkou prioritou má kritickou sekci, proces s vysokou prioritou žádá o povolení  procesor je přidělen procesu s vysokou prioritou, kde pak čeká na uvolnění  ale k tomu nemůže dojít, protože proces s nízkou prioritou nemůže získat procesor

37  algoritmus přístupu ke kritické sekci, vyžívající funkci testset  sdílená proměnná b se inicializuje na 0  pouze první proces Pi (který nastaví b) vstupuje do kritické sekce Process Pi: repeat repeat{} until testset(b); CS b:=0; RS forever Instrukce test-and-set

38 Instrukce xchg  instrukce xchg je dostupná u platformy Intel 86  sdílená proměnná b se inicializuje na 0  každý proces Pi má lokální proměnnou k  do CS může vstoupit pouze proces, který najde b=0  tento proces Pi vyloučí přístup ostatních procesů Pj nastavením b=1 Process Pi: repeat k:=1 repeat xchg(k,b) until k=0; CS b:=0; RS forever

39 OS řešení: semafory  synchronizační nástroj, nevyžadující aktivní čekání  semafory poskytuje programům OS  semafor je celočíselná proměnná, která je (s výjimkou inicializace) dostupná pouze prostřednictvím dvou atomických operací:  wait(S)  signal(S)  aby se vyloučilo aktivní čekání, je proces, který musí čekat, blokován a zařazen do fronty procesů, čekajících na stejnou událost  změnu stavu příslušného semaforu

40 Semafory  ve skutečnosti je tedy semafor datovou strukturou typu záznam: type semaphore = record count: integer; queue: list of process end; var S: semaphore;  když proces musí čekat na semafor S, je blokován a zařazen do fronty tohoto semaforu  operce signal odstraní jeden proces z fronty a přesune ho do seznamu procesů připravených ke spuštění  způsob výběru procesu určuje zvolená strategie, např. FIFO

41 Operace semaforu wait(S): S.count--; if (S.count<0) { block this process place this process in S.queue } signal(S): S.count++; if (S.count<=0) { remove a process P from S.queue place this process P on ready list } proměnnou count je nutné inicializovat na nezápornou hodnotu (aktuální hodnota závisí na potřebách aplikace)

42 Semafory: pozorování  Když je S.count >=0, je počet procesů, které mohou provést wait(S) bez blokování roven S.count  Když je S.count<0, je počet procesů čekajících na semafor S roven |S.count|  Atomicita a vzájemné vylučování:  žádné dva procesy nemohou být ve wait(S) a signal(S) (na tentýž S) ve stejném čase (platí i pro více procesorů)  programové bloky definující wait(S) a signal(S) jsou ve skutečnosti kritické sekce

43 Semafory: pozorování  kritické sekce definované ve wait(S) a signal(S) jsou velmi krátké  typicky 10 instrukcí  řešení:  jednoprocesorové: zákaz přerušení po dobu provádění operace  je to velmi krátká doba  nelze použít u víceprocesorového systému  víceprocesorové: použít některé z popsaných SW nebo HW řešení  rozsah aktivního čekání nsmí být velký

44 Použití semaforů pro řešení problému kritické sekce  Pro n procesů  inicializuj S.count na 1  pak má pouze 1 proces povoleno vstoupit do CS (vzájemné vylučování)  obecně platí, že inicializuj S.count na k lze povolit vstup do CS současně k procesům Process Pi: repeat wait(S); CS signal(S); RS forever

45 Použití semaforů pro synchronizaci procesů  máme dva procesy: P1 a P2  příkaz S1 v P1 musí být proveden dříve než příkaz S2 v P2  definujeme semafor synch  inicializujeme synch na 0  správnou synchronizaci zajistíme takto:  P1: S1; signal(synch);  P2: wait(synch); S2;

46 Binární semafory  semafory, které jsme zatím používali, nazýváme čítací nebo celočíselné semafory (counting semaphores, integer semaphores)  můžeme však použít i binární semafory  podobné čítacím semaforům, pouze proměnná ”count” je typu boolean  čítací semafory lze implementovat pomocí binárních semaforů...  použití binárních semaforů je obvykle náročnější než čítacích  např. je nelze inicializovat na hodnotu k > 1

47 Binární semafory waitB(S): if (S.value = 1) { S.value := 0; } else { block this process place this process in S.queue } signalB(S): if (S.queue is empty) { S.value := 1; } else { remove a process P from S.queue place this process P on ready list }

48 Spinlocks  čítací semafory, používající aktivní čekání (busy waiting) místo blokování (blocking)  jsou užitečné u víceprocesorových systémů, pokud kritická sekce netrvá dlouho  aktivním čekáním sice ztratíme malé množství času CPU, ale ušetříme tím čas potřebný pro přepnutí procesů wait(S): S--; while S<0 do{}; signal(S): S++;

49 Problémy se semafory  semafory jsou výkonným nástrojem pro řešení vzájemného vylučování a koordinace procesů  wait(S) a signal(S) jsou rozděleny do více procesů a proto je obtížné porozumět jejich působení  použití musí být korektní ve všech procesech  jediný chybný proces může způsobit problémy s celým souborem procesů

50 Problém obědvajících filozofů  5 filozofů u stolu pouze jí nebo přemýšlí  při jídle každý potřebuje 2 vidličky  k dispozici je pouze 5 vidliček ilustruje obtížnost alokace prostředků procesům bez vzájemného zablokování či vyhladovění (deadlock, starvation) klasický synchronizační problém

51 Problém obědvajících filozofů  každý filozof představuje jeden proces  potřebujeme jeden semafor pro každou vidličku:  fork: array[0..4] of semaphores  Initialization: fork[i].count:=1 for i:=0..4 Process Pi: repeat think; wait(fork[i]); wait(fork[i+1 mod 5]); eat; signal(fork[i+1 mod 5]); signal(fork[i]); forever  první pokus:  když každý filozof začne tím, že uchopí vidličku po své levici, nastává deadlock

52  řešení: dovolit začít jíst pouze 4 filozofům najednou  pak vždy alespoň 1 filozof může jíst, zatímco zbývající 3 musí čekat (s jednou vidličkou v ruce)  musíme tedy použít další semafor (např. T), který umožní omezit počet filozofů  Inicializace: T.count:=4 Process Pi: repeat think; wait(T); wait(fork[i]); wait(fork[i+1 mod 5]); eat; signal(fork[i+1 mod 5]); signal(fork[i]); signal(T); forever Problém obědvajících filozofů

53 Problém producenta a konzumenta  dva typy procesů:  producenti (producers)  konzumenti (consumers)  jeden nebo několik producentů produkuje data, která spotřebovává jeden nebo více konzumentů  např. programy produkují znaky, které pak jsou spotřebovány (vytištěny) tiskárnou  aby nevznikaly zbytečné čekací doby, je nutné zavést pro přechodné uskladnění produkovaných dat mezisklad - vyrovnávací paměť (buffer)  pro řízení lze použít dva semafory  jeden reprezentuje počet výrobků ve skladě  druhý signalizuje, zda lze vstoupit do skladu

54 Nekonečná vyrovnávací paměť b[2]b[3]b[4] outin b[1]b[5].. šedá oblast indikuje, která část bufferu je obsazena  vyrovnávací paměť (buffer) je pole, do kterého lze ukládat produkovaná data  paměť musí mít nezávislý přístup pro zápis a čtení (unbounded buffer)  in ukazuje na položku, do které se bude vkládat nový produkt  out ukazuje na položku, která bude konzumována

55 Funkce producenta producer: repeat produce item v; b[in] := v; in := in + 1 forever;

56 Funkce konzumenta consumer: repeat while in <= out do { nothing }; w := b[out]; out := out + 1; consume item w forever;

57 Kruhová vyrovnávací paměť out in b[1]b[5] šedá oblast indikuje, která část bufferu je obsazena  v praxi bývá velikost vyrovnávací paměti omezená  paměť je propojena do kruhu (kruhový buffer)  po n-té položce následuje opět první položka  při zaplnění bufferu musí producent čekat ! b[2] b[3] b[4] b[n] b[n-1] směr rotace

58 Producent s kruhovým bufferem producer: repeat produce item v; while ( (in + 1) mod n = out) do { nothing }; b[in] := v; in := (in + 1) mod n forever;

59 Konzument s kruhovým bufferem consumer repeat while in = out do { nothing }; w := b[out]; out := (out + 1) mod n; consume item w forever;

60 Potřebujete oholit?  u holiče jsou však jen 3 sedačky pro zákazníky a proto zde mohou obsluhovat pouze 3 holiči  na pohovce je místo k sezení jen pro 4 čekající zákazníky  ostatní zákazníci musí zůstat stát u dveří, dokud se neuvolní místo k sezení  do místnosti se vejde celkem nejvýše 20 zákazníků, ostatní musí čekat venku nebo odejít  pokladna pro placení je pouze jedna a inkasovat proto může pouze jeden holič

61 Barbershop Problem Vchod místo pro čekání ve stoje pohovka holící křesla Pokladna Východ

62 Barbershop Problem  když je holič volný, přesune se nejdéle čekající zákazník z pohovky na křeslo  nejdéle stojící zákazník pak usedne na pohovku  v daném okamžiku může platit jen jeden zákazník  holiči obsluhují zákazníky; pokud nečeká žádný zákazník, holiči spí

63 Co je nutné sledovat?  kapacitu krámu a pohovky  kapacitu holičů  umístění právě jednoho zákazníka do volného křesla  přítomnost zákazníka v křesle  placení zákazníka po opuštění křesla  přechod holiče na obsluhu pokladny

64 Barbershop Problem  /* program barbershop1 */  semaphore max_capacity = 20;  semaphore sofa = 4;  semaphore barber_chair = 3;  semaphore coord = 3;  semaphore cust_ready = 0, finished = 0, leave_b_chair = 0, payment= 0, receipt = 0;

65 Customer  void customer ()  {  wait(max_capacity);  enter_shop();  wait(sofa);  sit_on_sofa();  wait(barber_chair);  get_up_from_sofa();  signal(sofa);  sit_in_barber_chair;  signal(cust_ready);  wait(finished);  leave_barber_chair();  signal(leave_b_chair);  pay();  signal(payment);  wait(receipt);  exit_shop();  signal(max_capacity)  }

66 Barber  void barber()  {  while (true)  {  wait(cust_ready);  wait(coord);  cut_hair();  signal(coord);  signal(finished);  wait(leave_b_chair);  signal(barber_chair);  }

67 Cashier  void cashier()  {  while (true)  {  wait(payment);  wait(coord);  accept_pay();  signal(coord);  signal(receipt);  }

68 Monitory  konstrukce ve vyšším programovacím jazyce, poskytující stejné služby jako semafory, ale je snadněji ovladatelná  vyskytují se v řadě jazyků pro konkurenční programování (concurrent programming languages)  Concurrent Pascal, Modula-3, uC++, Java...  mohou být implementovány pomocí semaforů...

69 Monitor  je softwarový modul, obsahující:  jednu nebo více procedur  inicializační sekvenci  lokální datové proměnné  charakteristiky:  lokální proměnné jsou dostupné pouze prostřednictvím monitorových procedur  proces vstupuje do monitoru vyvoláním některé jeho procedury  v daném okamžiku může být v monitoru pouze jeden proces

70 Monitor  monitor zajišťuje vzájemné vylučování  program se tímto problémem nemusí zabývat  sdílená data jsou chráněna tím, že se nacházejí v monitoru  sdílená data jsou uzamčena v monitoru a procesy k nim mají přístup pouze prostřednictvím volání monitorových procedur  synchronizaci procesů zajišťuje programátor použitím podmínkových proměnných  reprezentují podmínky, které proces musí splnit před vstupem do monitoru

71 Podmínkové proměnné Condition variables  jsou lokálními proměnnými monitoru (dostupné pouze v monitoru)  lze k nim přistupovat a měnit je pouze následujícími 2 funkcemi:  cwait(a) blokuje provádění volajícího procesu podmínkou (proměnnou) a  proces může být znovu aktivován pouze když jiný proces provede csignal(a)  csignal(a) obnoví provádění některého procesu blokovaného podmínkou (proměnnou) a  pokud takových procesů existuje více, je vybrán jeden z nich  pokud žádný takový proces neexistuje, neprovede se nic

72 Monitor  čekající procesy jsou buď ve vstupní frontě nebo v podmínkové frontě  proces se umísťuje do podmínkové fronty c n sám provedením cwait (c n )  csignal (c n ) vpustí do monitoru jeden z procesů čekajících ve frontě c n  csignal (c n ) tedy blokuje volající proces a umísťuje ho do urgentní fronty (pokud ovšem csignal není poslední operaci monitorové procedury)

73  řešíme problém producentů a konzumentů  pro synchronizaci použijeme monitor  append() a take() jsou procedury monitoru  jsou to jediné procedury, umožňující procesům přístup k vyrovnávací paměti  pokud jsou tyto procedury korektní, bude synchronizace korektní pro všechny zúčastněné producenty i konzumenty ProducerI: repeat produce v; Append(v); forever ConsumerI: repeat Take(v); consume v; forever Monitor a problém svázaných P/C

74  Monitor potřebuje vyrovnávací paměť (sklad):  buffer: array[0..k-1] of items;  potřebuje dvě podmínkové proměnné:  notfull  csignal(notfull) indikuje že buffer není plný  notempty  csignal(notempty) indikuje, že buffer není prázdný  potřebuje ukazatele do bufferu a čítače:  nextin ukazuje na první volné místo pro přidávání  nextout ukazuje na aktuální položku k odebrání  count obsahuje počet položek v bufferu

75 Monitor boundedbuffer: buffer: array[0..k-1] of items; nextin:=0, nextout:=0, count:=0: integer; notfull, notempty: condition; Append(v): if (count=k) cwait(notfull); buffer[nextin]:= v; nextin:= nextin+1 mod k; count++; csignal(notempty); Take(v): if (count=0) cwait(notempty); v:= buffer[nextout]; nextout:= nextout+1 mod k; count--; csignal(notfull); Monitor a problém svázaných P/C

76 Předávání zpráv  je nutné vzájemné vylučování  dochází k výměně informací send (destination, message) receive (source, message)

77  vysílač a/nebo přijímač může (ale nemusí) být blokován  neblokující send, neblokující receive  neblokující send, blokující receive  vysílač po odeslání zprávy pokračuje  aby mohl připravovat zprávy co nejrychleji  přijímač je blokován, dokud zpráva není doručena  aby mohl okamžitě reagovat na doručení zprávy  blokující send, blokující receive  na doručení zprávy čeká přijímač i vysílač (rendezvous) Synchronizace při předávání zpráv

78 Adresace  přímá adresace  funkce send zahrnuje specifický identifikátor cílového procesu  funkce receive může předem určit, od kterého procesu je zpráva očekávána  zprávy od jiných procesů mohou být ignorovány  speciální adresa (např. 0) specifikuje, že zpráva může přijít od kteréhokoliv procesu  funkce receive může při volání dostat parametrem hodnotu, kterou má předat, když byla zpráva přijata  to umožňuje při neblokujícím receive zjistit, že došla zpráva

79 Adresace  nepřímá adresace  zprávy se zasílají do sdílené datové struktury, skládající se z front  říkáme jim poštovní schránky (mailboxes)  jeden proces posílá zprávy do schránky, druhý si zprávy ze schránky vyzvedává

80 Mailboxy a porty  mailbox může být vlastněn jedním párem vysílač/přijímač  tentýž mailbox může být sdílen několika vysílači a přijímači  OS pak může dovolit rozlišení více typů zpráv  Port je mailbox svázaný s jedním přijímačem a více vysílači  používá se pro aplikace typu klient/server (server je přijímačem)

81 Vlastnictví portů a mailboxů  port je obvykle vlastněn přijímačem  port se ruší ukončením procesu přijímače  mailbox vytváří OS na žádost procesu, který se tak stává jeho vlastníkem  mailbox se ruší na žádost procesu- vlastníka nebo když je tento proces ukončen

82 Obecný formát zprávy Message Contents záhlaví zprávy tělo zprávy Message Type Destination ID Source ID Message Length Control Info.

83 Problém čtenářů a pisatelů  jakýkoliv počet čtenářů může souběžně číst obsah souboru  v daném čase může do souboru zapisovat pouze jeden pisatel  pokud pisatel zapisuje do souboru, nemůže jeho obsah číst žádný čtenář

84 Dosažení vzájemného vylučování přenosem zpráv  vytvoření mailboxu mutex sdíleného n procesy  send() is neblokující  receive() je blokující když je mailbox mutex prázdný  Inicializace: send(mutex, “go”);  První proces P i, který provede receive() může vstoupit do CS  ostatní procesy budou blokovány dokud P i neodešle zprávu Process Pi: var msg: message; repeat receive(mutex,msg); CS send(mutex,msg); RS forever

85 Problém svázaných P/C přenosem zpráv  producenti umisťují položky odesíláním zpráv do mailboxu mayconsume  mailbox mayconsume slouží jako buffer: konzument může konzumovat, jestliže je v mailboxu alespoň jedna zpráva  Na začátku je mailbox mayproduce naplněn k prázdnými zprávami (k= velikost bufferu)  počet položek v bufferu se zvětší každým příchodem zprávy a zmenší každým odebráním zprávy  může obsluhovat více producentů i více konzumentů

86 Producer: var pmsg: message; repeat receive(mayproduce, pmsg); pmsg:= produce(); send(mayconsume, pmsg); forever Consumer: var cmsg: message; repeat receive(mayconsume, cmsg); consume(cmsg); send(mayproduce, null); forever Problém svázaných P/C přenosem zpráv


Stáhnout ppt "Operační systémy Přednášky pro výuku předmětu Operační systémy Ing. Antonín Vaněk, CSc. DFJP, Univerzita Pardubice září 2003."

Podobné prezentace


Reklamy Google