13AMP 4. přednáška Ing. Martin Molhanec, CSc.
Co jsme se naučili naposled Problém sdílených zdrojů Problém sdílených zdrojů Co je to kritická sekce Co je to kritická sekce Jak se dá současný přístup řešit pomocí semaforu Jak se dá současný přístup řešit pomocí semaforu Instrukce TAS (test and set) Instrukce TAS (test and set) Boolean a integer semafor Boolean a integer semafor
Semafor a jeho řešení 1. Speciální instrukce asembleru a)Test And Set b)Lock c)Exchange d)Get and Inc Přestože existuje několik možných instrukcí, které jsou implementovány v různých procesorech, jejich použití je víceméně ekvivalentní.
Speciální instrukce asembleru Test And Set (už známe) Test And Set (už známe) If sem=0 Then Flag:=false; Else sem:=0; Flag=true; End;
Speciální instrukce asembleru Exchange (prohození) Exchange (prohození) Reg :=: sem Což je totéž jako tmp := sem; sem := Reg; Reg := tmp;
Speciální instrukce asembleru Lock (zámek) Lock (zámek) while sem=0 do; sem := 0; Nejvíce podobné tomu, co chceme. Musí být přerušitelná v cyklu!
Speciální instrukce asembleru Inkrement (Dekrement) And Set Inkrement (Dekrement) And Set Sem := sem +1; Reg := Sem;
Semafor a jeho řešení 2. Softwarové řešení Nalezl holandský matematik T. DEKKER, které využívá 3 proměnné! Obtížné na pochopení!
Semafor a jeho řešení 2. Optimální Disable, Enable IRQ Nalezl matematik DJIKSTRA v roce Využívá pouze jedinou proměnnou! Dá se pochopit Nalezl matematik DJIKSTRA v roce Využívá pouze jedinou proměnnou! Dá se pochopit
Semafor a jeho řešení Obsazeno := true; {pomocná proměnná} RepeatDI; Obsazeno := Semafor; Semafor := True; EI; Until Not Obsazeno;
Pasivní semafor Procedure Wait(var sem); ; zjednodušeno ohledně kritická sekce begin while (sem=0) do; sem := 0; End; Nelze použít v kooperativním režimu Nelze použít v kooperativním režimu Užírá zbytečně čas CPU, protože zůstává ve stavu READY Užírá zbytečně čas CPU, protože zůstává ve stavu READY
Aktivní semafor Procedure Wait(var sem); ; zjednodušeno ohledně kritická sekce Begin if (sem=0) then Sleep(Q); sem := 0; End; Poznámka: fronta Q přináleží k semaforu sem. Poznámka: fronta Q přináleží k semaforu sem. Je nutný v kooperativním režimu Je nutný v kooperativním režimu Zbytečně nespotřebovává čas CPU, protože usne ve frontě u semaforu, je tedy ve stavu waiting! Zbytečně nespotřebovává čas CPU, protože usne ve frontě u semaforu, je tedy ve stavu waiting!
SLEEP(Q) Procedura SLEEP vloží právě běžící proces (running process) do fronty Q Procedura SLEEP vloží právě běžící proces (running process) do fronty Q a zavolá plánovač (scheduler), který vybere nový proces, který se stane procesem běžícím. Potom je nutné přepnout (TaskSwitch) procesy. a zavolá plánovač (scheduler), který vybere nový proces, který se stane procesem běžícím. Potom je nutné přepnout (TaskSwitch) procesy.
SLEEP(Q) Procedure Sleep(var Q: Queue); Var NewProc, OldProc: Process; Begin OldProcess := RunningProces;{pamatujeme si RP} Enqueue(RunningProcess, Q);{strčíme ho do Q} NewProc := Schedule;{najdeme nový P} RunningProcess := NewProc;{pamatujeme si ho} TaskSwitch(NewProc,OldProc);{přepneme procesy} End;
Enqueue, Dequeue, … Enqueue(P,Q) Enqueue(P,Q) –Vloží proces P do fronty Q Dequeue(Q): P Dequeue(Q): P –Z fronty Q vyzvedne proces P EmptyQueue(Q) EmptyQueue(Q) –Vrací True, když je fronta Q neprázdná!
SCHEDULE() {plánovací funkce, nalezne nový proces pro běh} Function Schedule: Process; Begin Schedule := Dequeue(ReadyQueue); End;
TaskSwitch(New,Old) Procedure TaskSwitch(var new,old: process); Begin {Zakážeme IRQ. Uložíme kontext. Uložíme kontext. Prohodíme zásobníky. Prohodíme zásobníky. Obnovíme kontext. Obnovíme kontext. Povolíme IRQ. }End;
Aktivní semafor Procedure Signal(sem); Begin sem := sem + 1; If Not EmptyQueue(Q) Then WakeUp(Q) Else Sleep(ReadyQueue); End;
WakeUp(Q) Procedura WAKEUP vloží právě běžící proces do fronty READY. Jako nový proces vezme proces z fronty Q. Pote se provede přepnutí procesů (TaskSwitch). Procedura WAKEUP vloží právě běžící proces do fronty READY. Jako nový proces vezme proces z fronty Q. Pote se provede přepnutí procesů (TaskSwitch).
WakeUp(Q) Procedure WakeUp(Q: Queue) Var NewProc, OldProc: Process; Begin OldProc := RunningProcess;{uložíme běžící} Enqueue(RunningProcess,ReadyProcess);{bude ready} NewProc := Dequeue(Q);{nový je ze fronty Q} RunningProcess := NewProc;{pamatujeme si ho} TaskSwitch(NewProc,OldProc);{přepneme procesy} End;
Semafor s frontou Budeme si semafor implementovat jako record. Semaphore = Record Queue : QueueType; Queue : QueueType; Counter : Integer; Counter : Integer;End;
Aktivní semafor Procedure Wait(var sem); ; zjednodušeno ohledně kritická sekce Begin if (sem.counter=0) then Sleep(sem.queue); sem.counter := 0; End;
Aktivní semafor Procedure Signal(sem); Begin sem.counter := sem.counter + 1; If Not EmptyQueue(sem.queue) Then WakeUp(sem.queue)Else Sleep(ReadyQueue); End;
poznámky Ve skutečnosti je nutné řešit další problémy Ve skutečnosti je nutné řešit další problémy –Co se má udělat když nějaká fronta bude prázdná! –Co dělat, když má fronta konečnou délku? –…
Jak realizovat frontu ? Jako pole Jako pole –Výhoda – je to jednoduché –Nevýhoda – omezení počtu prvků Jako seznam Jako seznam –Výhoda – téměř neomezený počet prvků –Nevýhoda – je to složitější Co vlastně do fronty ukládáme? Co vlastně do fronty ukládáme? –Nejlépe ukazatel (pointer) na PCB (process control block)
DEADLOCK Jedná se o vzájemné zablokování procesů. Jedná se o vzájemné zablokování procesů. Jednoduše řečeno – procesy na sebe vzájemně čekají. Jednoduše řečeno – procesy na sebe vzájemně čekají. Příklad: Honza a Michal stojí na každé straně dveří. Každý z nich čeká, až dveře otevře ten druhý. Žádný z nich se ovšem nedočká. Příklad: Honza a Michal stojí na každé straně dveří. Každý z nich čeká, až dveře otevře ten druhý. Žádný z nich se ovšem nedočká.
DEADLOCK PROCES A Wait(S1); Wait(S2);Signal(S2); Signal (S1); PROCES B Wait(S2); Wait(S1);Signal(S1); Signal (S2);
Postupový prostor
Jak zabránit DEADLOCKu? PREVENCE – procesy se programují tak, aby zmizely nebezpečné oblasti. Použijeme vnořené přidělování prostředků. PREVENCE – procesy se programují tak, aby zmizely nebezpečné oblasti. Použijeme vnořené přidělování prostředků. VYHÝBÁNÍ – vyhýbáme se nebezpečné oblasti bankéřův algoritmus. Při přidělení prostředku testujeme vstup do nebezpečné oblasti. VYHÝBÁNÍ – vyhýbáme se nebezpečné oblasti bankéřův algoritmus. Při přidělení prostředku testujeme vstup do nebezpečné oblasti. DETEKCE a ZOTAVENÍ – Deadlock se připustí, ale OS ho násilím vyřeší. Odebere a pak znovu přidělí procesu prostředek. DETEKCE a ZOTAVENÍ – Deadlock se připustí, ale OS ho násilím vyřeší. Odebere a pak znovu přidělí procesu prostředek.
Začíná to bejt nějaký složitý co ! Pěkně jsme si to zavařily!