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