11. přednáška politika přidělování místa, trashing -algoritmy určení oběti -souběžnost procesů -kritická sekce (co je to, požadavky, možnosti řešení, …) -synchronizace procesů (důsledky) -semafory Studijní materiály najdete na adrese:
Politika přidělování místa Frekvence výpadků Počet alokovaných rámců U W Neměnit alokaci rámců L - je potřeba řešit problém, kolik rámců procesu přidělit, pokud málo – zvýší se frekvence výpadků stránek, pokud hodně – omezí se možný stupeň multiprogramování - problém proměnnosti počtu, pokud se přidělí konstantní počet, určuje se při spuštění, v případě proměnného počtu (roste / klesá podle změny frekvence výpadků stránek – je zde vyšší režie operačního systému) - sledování frekvence výpadků - definuje se horní (U) a dolní (L) mez frekvence výpadků stránek - při překročení horní meze se procesu přidělí více rámců (pokud nejsou tak se proces odloží) - pokud klesne pod dolní mez, tak se procesu přidělí rámců méně
Trashing stupeň multiprogramování využití procesoru trashing (výprask) - v případě malého počtu aktivních procesů se prodlužují prodlevy při čekání na komunikaci (I/O, signalizace,...) - pokud je mnoho procesů (malé rezidentní množiny), dochází k častým výpadkům stránek - systém nedělá nic jiného, než zavádí stránky - ochrana před výpraskem (pevná alokace počtu rámců) - omezení stupně multitaskingu (procesy nejnižších priorit, procesy způsobující výpadky stránek, naposled běžící proces, největší proces, proces s nejdelší dobou dokončení,...)
Algoritmy určení oběti OPT (optimální nahrazování) - proces s 5 stránkami, rezidentní množina 3 stránky - oběť – nejpozdější ze všech následných odkazů - generuje nejmenší počet výpadků stránky - neimplementovatelný, srovnávací normál LRU (Least Recently Used) - obětí je nejdéle neodkazovaná stránka - princip lokality -> pravděpodobnost referencování je malá - výkon blízký OPT - velmi drahé řešení - velká režie - čítač má konečnou kapacitu
Algoritmy určení oběti FIFO - obětí je nejdéle zobrazená stránka ve FAP - rámce jsou organizovány do cyklického bufferu - když je buffer plný, nahrazuje se nejstarší stránka - méně efektivní, jednoduchá implementace "Máš ještě 1 šanci" / hodiny - výběr oběti – cyklické procházení rámci - referencí se získává "život" (nekumulativně) - výběrem za oběť se "život" ztrácí - oběť bez * se nahrazuje * *
Srovnání algoritmů určení oběti
Kooperace mezi procesy sdílení - procesy používají a modifikují sdílená data (soubory, proměnné, databázové záznamy), operace zápisu musí být vzájemně výlučné, zápis musí být výlučný se čtením, čtení může být realizováno souběžně, pro zabezpečení integrity dat se používají kritické sekce, sledy mají společnou datovou oblast komunikace - dají se koordinovat i procesy na jiném procesoru (počítači), může dojít k uváznutí v důsledku čekání na zprávu od jiného procesu, může dojít ke stárnutí (dva procesy si posílají zprávy, třetí se nemůže dočkat) P1P1 P2P2 událost zpráva P1P1 P2P2 D
Souběžnost procesů problém souběžnosti vzniká v prostředí prokládání i překrývání příčinou jsou sdílená data a prostředky, procesy používají a modifikují sdílená data, operace zápisu musí být vzájemně výlučná, operace zápisu musí být vzájemně výlučná s operací čtení, operace čtení bez modifikace mohou být souběžné kooperace mezi procesy, potřeba synchronizace běhu, čekání na událost vyvolanou jiným procesem neřízeným přístupem ke sdíleným údajům mohou procesy (sledy) získat nekonzistentní pohled na data, akce prováděné souběžnými procesy jsou závislé na pořadí prokládání jejich běhů obtížná lokalizace chyb programování výsledky procesů musí být nezávislé na rychlosti běhu jednotlivých procesů část kódu, kde se přistupuje ke sdílenému prostředku, se nazývá kritické sekce procesu sdružená s tímto prostředkem většinou je potřeba zajistit, aby v kritické sekci sdružené s jistým prostředkem, byl nejvýše jeden proces
void echo() { chin = getchar(); chout = chin; putchar(chout); } Proces1... chin = getchar();... chout = chin; putchar(chout);... Proces2... chin = getchar(); chout = chin;... putchar(chout); Vliv kritické sekce
Kritická sekce Modelové prostředí pro řešení problému kritické sekce: - každý proces běží nenulovou rychlostí - o relativní rychlosti procesů nelze vyslovit žádný předpoklad a řešení na nich nesmí záviset Požadavky: - vzájemné vyloučení (podmínka bezpečnosti) – Mutual Exclusion - trvalost postupu (podmínka živosti) – Progress - konečné čekání (podmínka spravedlivosti) - Fairness do {entry section KS exit section zbytek programu } while(1); entry section exit section zbytek programu ZP KS
Požadavky na řešení problému kritických sekcí Vzájemné vyloučení (podmínka bezpečnosti) – Mutual Exclusion Pokud proces P i je ve své kritické sekci, pak žádný další proces nesmí být ve své kritické sekci sdružené s týmž prostředkem. V každém okamžiku smí být v kritické sekci pouze jeden proces. Trvalost postupu (podmínka živosti) – Progress Rozhodování o tom, který proces vstoupí do KS, ovlivňují pouze procesy, které o vstup do kritické sekce usilují. Toto rozhodnutí pro žádný proces nemůže být odkládáno do nekonečna (nedodržení této podmínky může vést ke striktní alternaci dvou procesů). Konečné čekání (podmínka spravedlivosti) – Fairness Proces smí čekat na povolení vstupu do kritické sekce jen konečnou dobu. Musí existovat omezení počtu, kolikrát může být povolen vstup do KS sdružené s jistým prostředkem jiným procesům než procesu požadujícímu vstup v době mezi vydáním žádosti a jejím uspokojením. Pokud tedy proces usiluje o vstup do KS, nemohou tomu ostatní procesy zabránit tím, že se v kritické sekci neustále střídají (vstupují do ní zpravidla jednou).
Uváznutí - množina procesů P uvázla, pokud každý proces P i z množiny P čeká na událost, kterou vyvolá pouze některý z procesů z P - nutné (nepostačující) podmínky: vzájemné vyloučení (pouze jeden proces může používat prostředek), postupné uplatňování požadavků (Hold and Wait, proces může při žádosti o prostředek již něco vlastnit), nepřípustnost předbíhání (žádnému procesu se nesmí nic násilně odebrat) - postačující podmínka (důsledek nutných): cyklické čekání procesů - událost – uvolnění prostředku (paměť, soubor, I/O, …), zaslání zprávy Stárnutí - požadavky jednoho nebo více procesů nebudou splněny v konečném čase (priorita, prevence uváznutí, …) - některé operační systémy (Unix SVR4) problém uváznutí a stárnutí ignorují, tváří se, že tento problém neexistuje Uváznutí a stárnutí procesů Důsledkem snahy synchronizovat běh procesů je jejich uváznutí a stárnutí.
proces A proces B proces C proces D W X Y V NESMÍ NASTAT Vznik uváznutí procesů
Možnosti řešení problému kritické sekce Softwarové řešení aktivní čekání, naivní řešení, myšlenka zamykacích proměnných není zcela chybná Hardwarové řešení pomocí speciální instrukcí procesoru, opět aktivní čekání (busy waiting), snižuje se průchodnost OS Prostřednictvím operačního systému potřebné datové struktury určené k synchronizaci poskytuje OS (semafory), pasivní čekání (procesy nesoutěží o procesor), podpora volání synchronizačních služeb v programovacích systémech/jazycích (monitory, zasílání zpráv), hrozí uváznutí nebo stárnutí P 0 while(1) { while(obsazeno) ; obsazeno=1; KS; obsazeno=0; } P 1 while(1) { while(obsazeno) ; obsazeno=1; KS; obsazeno=0; } shared int obsazeno=0;
- na monoprocesoru se dosáhne vzájemného vyloučení - na multiprocesoru se vzájemného vyloučení nedosáhne (který procesor přijímá přerušení?) - obecně neakceptovatelné řešení - řešení speciálními instrukcemi, atomicky se provádí dvě akce se stejnou buňkou paměti (čtení a testování, výměna registrů) - akce jsou výlučné i v prostředí multiprocesoru HW řešení kritické sekce Proces P i do { disable interrupt KS enable interrupt ZP } while (1); Proces Pi do { do {} while testset(b); KS b=0; ZP while(1); testset(i) je-li i==0, i=1 vrací true je-li i==1 vrací false
Semafory - programový prostředek, který je umístěn na začátku kritické sekce. Pokud kolem něj projede proces, semafor reaguje změnou stavu. Semafory mohou být binární - první proces nastaví semafor na červenou, ostatní po dobu jejího trvání ztrácí procesor a odchází do fronty semaforu nebo obecné - stav se mění na hodnotu celého čísla - tradiční jméno binárního semaforu je mutex (mutual exclusion) - synchronizační prostředek poskytovaný operačním systémem - nahrazuje režim "busy waiting" pasivním čekáním - jedná se o zobecnění instrukce TST, nahrazení dvoustavové proměnné čítačem (v případě obecného semaforu) - poprvé popsal Edsger Wybe Dijkstra (1965) - původní pojmenování operací proberen (testovat) a verhogen (zvětšit) - stav semaforu >= 0 – počet procesů, které mohou plně provést službu wait (nepřejdou do fronty semaforu) - stav semaforu < 0 – počet čekajících procesů - pro stejný semafor nesmí být žádné dva procesy současně ve wait a signal, i v případě více procesorů - wait i signal jsou vlastně KS (typicky pouze desítky instrukcí)
kritická sekce fronta semaforu binární semafor PROCESY kritická sekce fronta semaforu binární semafor PROCESY Synchronizace binárním semaforem - binární semafor je implementován pomocí služeb lock a unlock. Lock zjistí hodnotu semaforu a nastaví jej - musí být implementováno jako nepřerušitelné. Pokud již je semafor nastaven (nějaký proces je v kritické sekci), uloží identifikační číslo aktivního procesu do fronty semaforu a suspenduje ho (proces suspenduje sám sebe). - unlock nejprve zkontroluje stav fronty, pokud je prázdná, nastaví semafor na zelenou. Každý proces tak vyvolá při vstupu do kritické sekce lock, při opouštění unlock. Parametrem služeb je semafor sekce. lock unlock do READY fronty
Obecný semafor - obecné semafory - kombinace fronty a číselné hodnoty, číslo udává, kolikrát je předplacena služba lock (kolikrát je možné ji provést, aniž by bylo potřeba proces zastavit), záporná hodnota udává, kolikrát se na semafor čeká - realizace obecného semaforu je provedena pomocí služeb WAIT a SIGNAL /* sem.h */ #define SFREE '1' #define SUSED '2' struct sentry { signed short semcnt, /* hodnota semaforu */ squeue; /* fronta */ }; extern struct sentry semaph[]; /* semafory */ Typ SEMAPHOR
Implementace služby WAIT #include /****************************** WAIT - převede aktuální proces do stavu čekání na semafor ******************************/ void wait(int sem){ register struct sentry *sptr; register struct pentry *pptr; sptr=&semaph[sem]; if(--(sptr->semcnt) < 0){ (pptr=&proctab[currpid])->pstate=PRWAIT; pptr->psem=sem; enqueue(currpid,sptr->squeue); resched() } - snížení hodnoty o 1, pokud je záporné, uloží se proces do fronty semaforu, stav se převede do WAIT, vyvolá se přeplánování - do tabulky procesů je poznamenán i semafor, pro snadnější lokalizaci procesu (není potřeba procházet všechny fronty)
Služba WAIT Služba SIGNAL - dekrementuje hodnotu semaforu - pokud je hodnota větší jak nula, proces pokračuje - v případě záporné hodnoty je proces zařazen do fronty semaforu - poznamená se, který semafor proces drží - provede se přeplánování - inkrekrementuje hodnotu semaforu - pokud je hodnota záporná nebo nulová, proces je zařazen do READY fronty (prioritní) - parametrem RESCHYES se zajistí okamžité přeplánování
Implementace služby SIGNAL #include /******************************* SIGNAL - implementace služby *******************************/ void signal(int sem) { register struct sentry *sptr; sptr=&semaph[sem]; if(++sptr->semcnt <= 0) ready(getfirst(sptr->squeue), RESCHYES); return OK; } hodnota se zvýší o 1, pokud je výsledek záporný nebo roven 0, převede se proces pomocí služby ready do prioritní fronty (z fronty semaforu)
Klasické synchronizační úlohy Producent – konzument (P-K) (Bounded – Buffer Problem) Jedná se o komunikaci mezi dvěma procesy. Čtenáři a písaři (Readers and Writers Problem) Jedná se o souběžnost čtení a modifikace dat (v databázi,...). Jsou možné dva přístupy: přednost čtenářů – žádný čtenář nebude muset čekat, pokud sdílený prostředek nebude obsazen písařem (kterýkoliv čtenář čeká pouze na opuštění KS písařem – písaři mohou stárnout), přednost písařů – jakmile je některý písař připraven vstoupit do KS, čeká jen na její uvolnění čtenářem nebo písařem. Připravený písař tedy předbíhá všechny připravené čtenáře – čtenáři mohou stárnout. Úloha o večeřících filozofech (Dining Philosophers Problem) Jedná se o zajímavý ilustrační problém pro řešení uváznutí. 5 filozofů buď přemýšlí nebo jí, jedí rozvařené (tedy klouzavé) špagety a potřebují tedy 2 hůlky. Co se stane, když všech 5 filozofů najednou uchopí např. své pravé hůlky? (Časem všichni umřou hlady)
PRODUCENTKONZUMENT - jeden proces vyčká na událost generovanou druhým procesem - proces může být pouze v jedné frontě, z fronty binárního semaforu odchází přes službu resume do ready fronty - některé implementace nevhodné pro binární semafory (výměna dat přes sdílenou paměť) - modelový případ producent – konzument (obecné paradigma kooperace procesů) - buffer s produkovanými a dosud nezpracovanými položkami (buffer konečné kapacity k) Synchronizace P-K obecným semaforem
Kód producentaKód konzumenta for(;;) { char data=vytvor_data(); char data; wait(B); wait(A); uloz_do_sdilene_pameti(); data=cti_ze_sdilene_pameti(); signal(A); signal(B); } zpracuj_data(); } - pomocí implementace obecných semaforů se zajistí efektivní fungování mezi konzumentem a producentem - semafor A je inicializován na 0, semafor B je inicializován na velikost sdílené paměti -v případě souběhu producenta a konzumenta jsou data obhospodařována průběžně, v jiném případě se zastaví produkce, nebo čerpání - návaznost na inkrementaci semaforu ve službě KILL (stav WAIT), kdy se proces odstraňuje z každé fronty