440 likes | 636 Views
12. přednáška 14. 12. 2011 řešení kritické sekce ( SW, HW, systémové prostředky ) semafory klasické synchronizační problémy synchronizace semaforem modelování uváznutí ochrana před uváznutím prevence uváznutí hierarchické uspořádání prostředků obcházení uváznutí detekce zablokování
E N D
12. přednáška • 14.12. 2011 • řešení kritické sekce (SW, HW, systémové prostředky) • semafory • klasické synchronizační problémy • synchronizace semaforem • modelování uváznutí • ochrana před uváznutím • prevence uváznutí • hierarchické uspořádání prostředků • obcházení uváznutí • detekce zablokování • správa I/O zřízení • Win32 API (platformy, objekty, procesy, zásobník, priorita, ...) • Studijní materiály najdete na adrese: • http://www.uai.fme.vutbr.cz/~vdumek/
shared int obsazeno=0; P0 while(1) { while(obsazeno) ; obsazeno=1; KS; obsazeno=0; } P1 while(1) { while(obsazeno) ; obsazeno=1; KS; obsazeno=0; } 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í
SW řešení kritické sekce • softwarové řešení na aplikační úrovni – algoritmy, jejichž správnost se nespoléhá na žádnou další podporu, základní (a problematické) řešení s aktivním čekáním (busy waiting) • sdílená zamykací proměnná (nic neřeší) • striktní střídání dvou procesů – závislost na rychlosti procesů, takže řešení je nepřípustné • Petersonovo řešení – dvě globální proměnné boolean interest[2], int turn
HW řešení kritické sekce - na monoprocesoru se dosáhne vzájemného vyloučení - snižuje se efektivnost (nelze prokládat běh procesu v KS a procesů v ZP) - 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 Proces Pi 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
HW řešení kritické sekce – instrukce xchg Proces Pi do { k = 1; do { xchg(k, b); } while(k != 0); KS b = 0; ZP } while (1); - atomická instrukce pro výměnu obsahu proměnných - u procesorů Pentium - xchg má stejné nedostatky jako TST - sdílená proměnná b je inicializována na 0 každý Pi má svoji lokální proměnnou k - proces, který zjistí b == 0 vstoupí do KS - vyloučí všechny ostatní procesy Pj nastavením b = 1
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í)
11 binární semafor 110 587 kritická sekce PROCESY fronta semaforu 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. binární semafor 587 lock PROCESY 11 kritická sekce 110 fronta semaforu 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 - 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) #include <conf.h> #include <kernel.h> #include <proc.h> #include <q.h> #include <sem.h> /****************************** 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() } }
SlužbaWAIT • 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í SlužbaSIGNAL • 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 hodnota se zvýší o 1, pokud je výsledek zápornýnebo roven 0, převede se proces pomocí služby ready doprioritní fronty (z fronty semaforu) #include <conf.h> #include <kernel.h> #include <proc.h> #include <q.h> #include <sem.h> /******************************* 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; }
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)
PRODUCENT KONZUMENT Synchronizace P-K obecným semaforem - 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)
- pomocí implementace obecných semaforů se zajistí efektivní fungování mezi konzumentem a producentem Kód producenta Kód konzumenta for(;;) 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(); } • - 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
A proces V držení P2 požadavek prostředek se čtyřmi instancemi P1 požadavek V držení B Modelování uváznutí - alokační graf (graf přidělování zdrojů), znázornění přidělených a požadovaných prostředků, počet instancí každého prostředku, Resource Allocation Graph (RAG) - prostředek Ri má Wi instancí, jsou opakovaně přístupné (žádost, používání, uvolnění) - uzly: prostředky, procesy, hrany: požadavkové (orientace z procesu na prostředek), přidělovací (orientace z prostředku na proces) - pokud alokační graf neobsahuje cyklus – není uváznutí - pokud alokační graf obsahuje cyklus – jedinečné prostředky = uváznutí, násobné prostředky (více instancí) = nemusí uváznout proces vlastní prostředek proces požaduje prostředek
Neobsahuje cyklus Obsahuje cyklus R1 R3 P1 P2 P3 R1 R3 R4 R2 R4 R2 P1 P2 P3 Ochrana před uváznutím - prevence: ruší se platnost některé nutné podmínky, k uváznutí nikdy nedojde - detekce: detekuje se existence uváznutí, řeší se následky - obcházení: zamezuje se současné platnosti nutných podmínek, prostředek se nepřidělí, pokud by hrozilo uváznutí, hrozí stárnutí - ignorace: nejjednodušší metoda („pštrosí metoda“), pokud k uváznutí dojde – reboot, nelze použít pro životně kritické systémy
Prevence uváznutí - konzervativní politika, omezuje se přidělování prostředků, přímé a nepřímé metody - nepřímé metody – zneplatnění některé nutné podmínky (virtualizace prostředků, přidělení všech prostředků najednou, odebírání prostředků) - přímé metody – nepřipuštění platnosti postačující podmínky (uspořádání pořadí přidělování prostředků) - virtualizace – nepřímá metoda, rušení vzájemné výlučnosti, mimo spooling nepoužitelné - požadování všech prostředků najednou – nepřímá metoda, při žádosti o prostředek nesmí proces nic vlastnit, nebezpečí stárnutí procesu, vhodné pro procesy s jednou nárazovou činností, neefektivní, možná prodleva při zahájení procesu - odebírání prostředku – jen když lze uchovat stav prostředku (odebírání procesoru, paměti), ruší se vlastnost nepředbíhatelnosti procesů při používání prostředku, dvě možnosti (odmítnutý proces uvolní vše co vlastní a požádá o vše znovu, pokud požadovaný prostředek vlastní jiný proces, je tento požádán o uvolnění všeho a o znovupožádání o vše), použitelné pro prostředky s uchovatelným a obnovitelným stavem, režijní ztráty, možnost cyklického restartu - preventivní metody jsou jednoduché, neefektivní
0 volný prostředek Uspořádané prostředky 1 nezablokovatelný proces 5487 2 proces 1136 3 proces 25 4 5 - proces 5487 nemůže být zablokován, může žádat pouze o prostředek 0, 1 6 7 8 Princip hierarchického uspořádání prostředků - hierarchická strategie se často kombinuje se strategií úplného vyhraze- ní (na jedné úrovni nebývá jeden prostředek, ale celá skupina - stále příliš defenzívní, lze zlepšit vhodnou volbou posloupnosti pro- středků
Obcházení uváznutí • zamezuje současné platnosti nutných podmínek • připouští se tak více souběžnosti než při prevenci • dva přístupy – nespustí se proces, jehož požadavky by mohly vést k uváznutí, neprovede se přidělení prostředku, pokud by to mohlo vést k uváznutí • prostředky jsou podle svého typu rozděleny do kategorií • každý typ prostředku se vyskytuje v jistém počtu exemplářů, rozdělení závisí na konfiguraci systému (tiskárny podle kvality tisku, disky podle rychlosti, různé komunikační kanály, …) • musí se znát maximum požadovaných prostředků každého procesu, aby mohl proces existovat, musí deklarovat předem svoje C(j, i)
Obcházení uváznutí existující prostředky pro všechny typy prostředků i a procesy j požadované prostředky pro všechny typy prostředků i a procesy j počet přidělených prostředků typu i procesu j souhrnný počet dostupných prostředků typu i počet prostředků typu i potřebných pro dokončení procesu j souhrnný počet nevyžádaných prostředků typu i nový proces smí vzniknout jen když platí
Obcházení uváznutí • - nejvýhodnější je nalezení strategie, která by neomezovala, dokud se neobjeví nebezpečí zablokování, přidělení prostředku je pozastaveno až do okamžiku, kdy se situace zlepší - bankéřův algoritmus • - název úlohy ze situace v reálném světě (bankéř přidělující finanční prostředky v různých měnách, podmínkou je znalost maximálních požadavků zákazníků - operační systém zná požadavky procesů na čerpání prostředků) • pokud existuje alespoň jedno pořadí požadavků, při kterém nedojde k zablokování (všichni klienti banky budou moci splnit své záměry), může operační systém toto pořadí vynutit selektivním splňováním požadavků • bankéř prostředek přidělí, pokud systém po přidělení zůstane v bezpečném stavu • proces vznikne jen tehdy, když lze uspokojit všechny jeho požadavky (v jakémkoli pořadí)
Bankéřův algoritmus • máme 3 typy prostředků následujícího složení: • R(1) = 9 R(2) = 3 R(3) = 6 • - 4 procesy s počátečním stavem S: - předpokládejme, že P2 požaduje Q = (1, 0, 1)
1,1,2 1,0,1 0,1,1 5,1,1 1,0,1 6,1,2 - + Bankéřův algoritmus • výsledný stav po uspokojení požadavku P2 Q = (1, 0, 1) - stav je bezpečný pro posloupnost { P2, P1, P3, P4}(po dokončení P2 máme W(V) = (6, 2, 3), což umožňuje dokončení procesu P1) - požadavek se uspokojí
1,1,2 1,0,1 0,1,1 1,0,0 1,0,1 2,0,1 - + Bankéřův algoritmus • pokud P1 požaduje Q = (1, 0, 1), je výsledný stav: - stav není bezpečný, každému procesu by chyběla instance prostředku R1 - požadavek se odmítne, P1 bude čekat
Detekce zablokování - liberální politika, každý dostává co chce a kdy chce, existenci uváznutí periodicky testuje operační systém - výhoda: žádný proces nemusí čekat na své zahájení, nevýhoda: nutnost řešit uváznutí a posteriori - řešení: zrušení všech uváznutých procesů(nejčastěji použitá metoda), návrat uváznutých procesů k poslednímu kontrolnímu bodu(možnost opakování situace), postupně rušit uváznuté procesy(podle spotřebovaného času procesoru, podle času do dokončení procesu, podle priority, podle množství vlastněných prostředků), postupně předbíhat uváznuté procesy
Správa I/O zařízení (periferií) • Klasifikace I/O zařízení: • - pro lidské rozhraní (komunikace s uživatelem, terminály s displeji, klávesnice, myš, tiskárna) • pro strojové rozhraní (disky, pásky, řadiče, senzory, komunikace modemy, komunikace síťovými rozhraními) • - rozdíly klasifikovaných zařízení: v rychlosti přenosu dat, ve složitosti ovládání, v objemech přenosu (byte – desítky KB), v kódování dat, v chybovosti a reakcích na chyby • - znaková (klávesnice, displeje, terminály, tiskárny, myši, plottery, tablety), bloková (disky, pásky), speciální (časovač, speaker, …) • - požadavek transparentnosti přístupu k zařízením (stejný přístup jako k souborům, až při běhu programu lze určit, kam výstup půjde) • - přidávání nových druhů zařízení: zásah do jádra OS (Unix), instalovatelné ovladače zařízení, kombinace obou způsobů • - ovladače zařízení mají tři části: obslužný program přerušení, část závislá na zařízení, část nezávislá na zařízení (správce vyrovnávací paměti, přidělení jména zařízení, …)
Správa I/O zařízení (periferií) - vstupní a výstupní zařízení - od notoricky známých až po zbraně, traktory, obráběcí stroje, vlhkoměry, … - řízení periferií pomocí speciálních I/O obvodů - kanálů, jedná se o komunikaci s jiným procesorem - hlavním úkolem operačního systému není přímé ovládání periferie, ale její korektní přidělování jednotlivým procesům, služby pro manipulaci s periferií jsou na daleko vyšší úrovni, než jakou nabízí samo zařízení, sdílení a ochrana zařízení - tyto služby nemusí být součástí operačního systému, mohou být soustředěny ve sdílených knihovnách - rozeznáváme zařízení: vyhrazená, sdílená, společná - vyhrazená: nemohou sloužit více procesům současně, pro každé takové zařízení je potřeba správce, který využívá různých technik
Správa I/O zařízení (periferií) Vyhrazená zařízení - vyhrazování zařízení - základní a nejjednodušší mechanismus, správce nedovolí používat zařízení nikomu, pokud je první proces neuvolní - zařízení bývají přidělována podle pořadí požadavků, jedná se o obdobu binárních semaforů v kritických sekcích, jednoduché s vysokou pravděpodobností zablokování - virtualizace - přesvědčení procesu, že má k dispozici neomezený počet vyhrazených zařízení (prakticky existuje omezení velikostí odkládacího prostoru), každý proces potom může dostat svoje zařízení - zařízení se přidělí systémovému procesu (serveru), který je bude ovládat a nabízet svým klientům (ostatním procesům), pro obrazovku zvláštní okno, zvukový výstup promíchán, pro tiskárnu se použije spooling (speciální soubor na disku), virtualizaci nemá význam používat pro její náročnost u málo frekventovaných zařízení
Správa I/O zařízení (periferií) • Sdílená zařízení • - svoji kapacitu mohou dělit na části a každá z nich je k dispozici jinému procesu, není je potřeba vyhrazovat, ale je potřeba správce, který je bude rozdělovat a starat se o přidělování jednotlivých částí • Společná zařízení • - mohou sloužit bez jakéhokoliv problému více procesům, při vhodné technické realizaci nepotřebují správce (hodiny, mikrofon, …), pokud správce je, je velice triviální, pokud má zařízení nabízet širší služby, je třeba vytvořit server pro správu tohoto zařízení, které se potom chová jako vyhrazené (možnost virtualizace) • hlavním úkolem správce zařízení je starat se o jeho přidělení jednotlivým procesům, nikoliv jeho přímým ovládáním • - procesy neovládají samy zařízení: zařízení je ovládáno serverem nebo je virtualizováno, vyšší ovládání zařízení pomocí sdílených knihoven
Platformy rozhraní Win32 API • - API - Application Programming Interface, množina funkcí • - implementace na platformách: • Win32s • - mapovací vrstva z 32 b. na 16 b., pro Windows 3.x, používá mechanismus roubování (thunking), konvertuje 32 b. parametry na 16 b., platforma Win32s nerozšiřuje možnosti operačního systému, řada funkcí je realizována jako slepé (stub) - hned se vrátí a hlásí chybu (16 b. Win nepodporují toky -> funkce CreateThread vrací NULL), některá rozšíření (strukturovaná obsluha výjimek, částečná implementace paměťově mapovaných souborů), vytvořena pro vytváření 32 b. aplikací ještě před příchodem oficiální platformy, nijak zvlášť se neujala. • Windows NT (Win 32 pro 64 bitů) • platforma s výhledem do budoucnosti, žádné pozůstatky z MS DOSu, značné nároky na velikost paměti a disku, velice robustní, brání přímému přístupu k HW počítače, přenositelnost (C++, MIPS, Alpha, PowerPC) – potřeba překladu pro daný procesor, jádro a HAL (Hardware Abstraction Layer) je potřeba přepsat speciálně pro jinou architekturu (assembler), podpora více procesorů. • Windows 95 (Windows 98) • - první 32 b. platforma s širokým použitím, lepší implementace Win32 API než Win32s (nikoliv úplná), HW nedostatečný pro Windows NT, omezená podpora pro funkce bezpečnostní, sledování událostí, ladící, pro práci s registry, velmi přijatelná a výkonná. • Windows CE • - pro kapesní počítače, bez podpory virtuální paměti, podpora paměťově mapovaných souborů, strukturovaná obsluha výjimek, registry, DLL, preemptivní multitasking, přenositelná.
Objekty jádra • objekty se vytváří voláním různých funkcí rozhraní Win32 API (paměťově mapované soubory, semafory, procesy, prováděcí toky, události) • - objekt jádra je tvořen vyhrazeným úsekem paměti, datová struktura se složkami o objektu, přístup k datovým strukturám má pouze jádro • zachování konzistentních objektů jádra – případné změny neovlivní existující aplikace • přístup aplikací výhradně přes API funkce • přístup k objektům přes handle (rukojeť), 32 bitové číslo, může ho použít kterýkoliv tok • - objekty jádra vlastní jádro, při zrušení procesu objekt může dále existovat (použití jiným procesem) Počítadlo odkazů - objekt má počítadlo odkazů, inkrementace - při vzniku objektu nastaveno na hodnotu 1 - dekrementace při ukončení procesu - při dosažení hodnoty 0 je objekt zrušen Zabezpečení - popisovač zabezpečení k ochraně objektu - vytvoření, přístup, použití, zákaz - pro serverové aplikace
Tabulka handlů objektů jádra - při inicializaci procesu alokace tabulky handlů objektů jádra - podrobnosti o struktuře a správě tabulky nedokumentovány - návratová hodnota NULL ( CreateFile -1) typedef struct _TAB_HANDLE { INT index; VOID handle; DWORD maska; DWORD priznak; }; Vytvoření objektu jádra - při inicializaci procesu je tabulka prázdná, při vytvoření objektu se alokuje paměť a přiřadí se první položka, ukazatel na interní adresu bloku paměti objektu, maska na plný přístup - funkce pro vytvoření objektu vrací handle vztažený k volajícímu procesu, použitelný pro všechny prováděcí toky volajícího procesu - skutečné hodnoty handlů mohou být různé (nedokumentováno)
Objekty jádra Zavření objektu jádra - BOOL CloseHandle(HANDLE hobj) - při existenci objektu v tabulce volajícího procesu TRUE (jinak FALSE) - dekrementace počitadla odkazů (0 – zrušení), zrušení odpovídající položky v tabulce handlů - počitadlo <> 0 – objekt stále existuje (slouží pro jiný proces), volající proces už jej nemůže používat - při ukončení procesu je prohlížena tabulka handlů a všechny aktivní handly jsou zrušeny (v případě počitadla=0 jsou i odstraněny) Sdílení objektů jádra mezi procesy - sdílení bloků dat mezi dvěma procesy na stejném počítači (mapování souborů), předávání bloků dat mezi procesy na různých počítačích (poštovní přihrádky, roury), synchronizace prováděcích toků různých procesů (mutexy, semafory, události) - handly objektů jádra se vztahují pouze k jednomu procesu - zajištění robustnosti operačního systému, nelze zajistit při celosystémovém přidělování handlů - zabezpečení (systém autorizace handlů vlastníkem)
Objekty jádra Dědičnost handlů - použití v případě rodičovství, objekt je vytvářen s příznakem dědičnosti, dědí se pouze handly (nikoliv objekty) - při vytvoření synovského procesu je vytvořena nová tabulka handlů a všechny řádky s příznakem dědičnosti v tabulce rodiče jsou zkopírovány (na stejné místo => stejný handle), inkrementace počitadla odkazů (využívání objektu více procesy) - rodič může zavřít handle bezprostředně po návratu z funkce Create…, aniž by omezil možnost manipulovat potomkovi s objektem - dědičnost funguje stejným způsobem i na další generace - dědění probíhá pouze v okamžiku vytváření potomka (pozdější objekty už nejsou zkopírovány do tabulky potomků) , možnost změny příznaků RODIČ POTOMEK
Objekty jádra Pojmenované objekty - další způsob sdílení objektů jádra, jméno objektu je parametrem funkce Create… (MAX_PATH znaků (260), nesmí obsahovat \, stejný prostor jmen) - nemusí být příznak dědičnosti, je možné sdílet i mezi nepříbuznými procesy - stejný typ objektu Semaphore BERTA HANDLE CreateSemaphore(…, …, …, "BERTA"); HANDLE CreateSemaphore(…, …, …, "BERTA"); Proces A Proces B
Objekty jádra Duplikace handlů - kopírování položky z jedné tabulky handlů do druhé - mohou kooperovat tři procesy (zdrojový, cílový, aktivační) nebo dva procesy Procesy - instance běžícího programu, k dispozici má paměťový prostor 4 GB, inertní - různé prostředky (soubory, dynamicky alokovaná paměť, prováděcí toky, …) - automatické uvolnění při ukončení procesu - za provádění kódu je zodpovědný prováděcí tok - kontext toku (registry procesoru, zásobník) - proces bez prováděcího toku je zrušen i se svým paměťovým prostorem - cyklické přidělování procesorového času jednotlivým tokům - primární prováděcí tok, vnořené toky - proces : prováděcí tok (1 : 1 MS DOS, Unix V, IRIX; 1 : M NT, Solaris) - souběžný běh prováděcích toků na víceprocesorových strojích - dva typy aplikací v prostředí Win32 API – graficky orientované (GUI), textově orientované (CUI - konzolové), hranice nejasná, systémový zavaděč
Cyklické přidělování procesoru - funkce CreateProcess - objekt jádra typu proces, počitadlo odkazů = 1, vytvoření adresového prostoru (data, EXE, DLL), primární prováděcí tok - spouštěcí kód runtimové knihovny s voláním funkce WinMain - ukončení procesu třemi způsoby: 1. nejběžnější, nastavení návratové hodnoty procesu , nevrací žádnou hodnotu, zánik všech prováděcích toků, následující kód se neprovede 2. nedoporučuje se, volá prováděcí tok jiného procesu, asociované DLL se nemusí dozvědět o ukončení procesu 3. velmi zřídka 1. VOID ExitProcess(UINT fuExitCode) 2. BOOL TerminateProcess(HANDLE hProcess, UINT fuExitCode) 3. zánik všech prováděcích toků - primární prováděcí tok jediným tokem v procesu (obvyklé) - elegantnější řešení než periodické dotazování (velké časové zpoždění) - každý prováděcí tok může mít přiřazen vlastní procesor (počet toků > počet procesorů) - každý tok vlastní zásobník alokovaný v 4 GB procesního adresového prostoru
Prováděcí toky - při použití statických a globálních proměnných může dojít k poškození - v případě automatických a lokálních proměnných se používá zásobník - implicitně je nastaven 1 MB paměťového prostoru, přiděleny dvě fyzické stránky, lze měnit během linkování aplikace (/STACK:rezervovat[, přidělit]) Stav stránky Adresa paměti - přidělení dvou stránek fyzického prostoru - ukazatel na nejvyšší stránku zásobníku - hlídací stránka (guard page) - při snaze použít hlídací stránku se zásobníku přidělí další fyzická stránka - odstranění příznaku PAGE_GUARD a jeho přesunutí na novou hlídací stránku - růst zásobníku jen v případě nutnosti - nejspodnější stránka nemá nikdy přidělen fyzický prostor - přidělení fyzické stránky na adresu 0x08001000 se vyvolá výjimka přetečení zásobníku - při pokusu o přístup na adresu 0x08000000 je proces zrušen Vrchol zásobníku - přidělena fyzická stránka 0x080FF000 Fyzická stránka přidělena, nastaven příznak ochrany PAGE_GUARD 0x080FE000 0x080FD000 Rezervovaná stránka … … 0x08003000 Rezervovaná stránka 0x08002000 Rezervovaná stránka 0x08001000 Rezervovaná stránka Dno zásobníku - rezervovaná stránka 0x08000000 Počáteční nastavení zásobníku
Stav stránky Stav stránky Adresa paměti Adresa paměti Vrchol zásobníku - přidělena fyzická stránka Vrchol zásobníku - přidělena fyzická stránka 0x080FF000 0x080FF000 0x080FE000 Přidělena fyzická stránka 0x080FE000 Přidělena fyzická stránka 0x080FD000 Přidělena fyzická stránka 0x080FD000 Přidělena fyzická stránka … … … … 0x08003000 0x08003000 Přidělena fyzická stránka Přidělena fyzická stránka Fyzická stránka přidělena, nastaven příznak ochrany PAGE_GUARD 0x08002000 Přidělena fyzická stránka 0x080FE000 0x08001000 Přidělena fyzická stránka Dno zásobníku - rezervovaná stránka 0x08001000 Rezervovaná stránka 0x08000000 Dno zásobníku - rezervovaná stránka 0x08000000 Plný zásobník toku Téměř zaplněný zásobník toku - prováděcí tok má svoji sadu registrů procesoru – kontext toku, struktura CONTEXT je jedinou, která je závislá na typu procesoru, odráží stav registrů v době posledního běhu toku (x86, MIPS, Alpha, PowerPC) - kontext také obsahuje registr IP a vrchol zásobníku - registry naplněny kontextem po přidělení procesorového času
Prováděcí čas toku - pomocí funkce GetThreadTimes je možné získat: CreationTime (čas vytvoření) · kdy byl prováděcí tok vytvořen Exit Time (čas ukončení) · kdy byl prováděcí tok ukončen, pokud tok ještě běží, je hodnota nedefinována KernelTime (čas jádra) · množství času, které tok strávil vykonáváním kódu operačního systému UserTime (uživatelský čas) · množství času, které tok strávil vykonáváním kódu aplikace - pro veškeré manipulace s tokem jsou k dispozici funkce Win32 API (Create, Exit, Terminate, …) Plánování toků - modifikace algoritmů pro jednotlivé platformy Win32 API - plánování prováděcích toků se děje na základě jejich priority - priorita nastavena v rozmezí 0 (nejnižší) až 31 (nejvyšší) - Zero Page Thread – tok s nejnižší prioritou, nemůže mít žádný jiný tok - přidělování procesorového času tokům s nejvyšší prioritou (starvation) - prováděcí toky často nemají důvod k činnosti – obsloužení i nízkých priorit - běh prováděcího toku s prioritou n je ihned zastaven tokem s prioritou n+1
- priorita se přiděluje ve dvou krocích (třída priority procesu, prioritní offset prováděcího toku v rámci třídy procesu) - třída procesu: čekací, normální, vysoká, realtime - pokud třída priority není určena, nastaví systém prioritu normální (pokud rodič neběží v čekací třídě) - většina uživatelských procesů běží v normální třídě – procesy na popředí, ostatní jsou procesy běžící na pozadí - při provádění procesu na popředí se časové kvantum zvýší trojnásobně (NT) nebo se priorita všech jeho toků zvýší o 1 (Win95) - čekací třída – monitorovací akce, šetřiče obrazovky, vysoká třída – pouze výjimečně (reakce i při zacyklení procesu nižší úrovně), realtime je naprostou vzácností (komunikace s hardwarem, většina procesů s nižší prioritou) - v případě oprávnění je umožněno procesům libovolně měnit prioritu
- priorita prováděcího toku se nastavuje vzhledem ke třídě procesu - snižovat, zvyšovat, BOOL SetThreadPriority(HANDLE hThread, int nPriority) - první vytvoření prováděcího toku (NORMAL) - modifikace pomocí speciálních parametrů: THREAD_PRIORITY_IDLE THREAD_PRIORITY_TIME_CRITICAL
- tabulka znázorňuje priority prováděcích toků odpovídající procesům běžícím na pozadí, při přesunu na popředí se v NT úrovně nemění, pouze se zvýší časová kvanta, u Win95 se u toků s vysokou, zvýšenou, normální, sníženou a nízkou relativní prioritou zvýší úrovně o 1, toky s čekací a kritickou prioritou se nemění - v rozhraní Win32 API neexistuje žádná funkce, která by vracela úroveň priority prováděcí toku, chování plánovacího algoritmu je zvoleno experimentálně - neměly by se vytvářet aplikace, které budou spoléhat na konkrétní chování plánovacího algoritmu Dynamická úprava prioroty - kombinace třídy a relativní hodnoty – bázová úroveň - reakcí na události (zpráva) se bázová priorita zvyšuje o 2, přidělí se procesor a celé kvantum pro přečtení, po skončení toku se jeho priorita sníží o 1, při příštím přidělení procesoru se nechá opět proběhnout celé kvantum a priorita se sníží na původní bázovou hodnotu - algoritmy pro dynamickou změnu priority se neustále mění, nikdy se neupravuje priorita realtimových toků, ani se neprovádí úprava na realtimovou úroveň - pro NT jsou k dispozici funkce k zakázání a povolení úpravy (zvyšování) priority a funkce na zjištění stavu tohoto mechanizmu