syn chroniz ácia procesov

39
6.1 ©2009 Operating System Concepts Synchronizácia procesov Background Problém kritickej sekcie Petersonovo riešenie Synchronizačný hardvér Semafory Klasické problémy synchronizácie Monitory Synchronizačné príklady

Upload: morley

Post on 10-Jan-2016

58 views

Category:

Documents


9 download

DESCRIPTION

Syn chroniz ácia procesov. Background Probl é m kritickej sekcie Peterson ovo riešenie Synchroniza čný h ard vér Sema fory K lasic ké p robl émy s ynchroniz ácie Monitor y Synchroniza čné príklady. Ciele. - PowerPoint PPT Presentation

TRANSCRIPT

6.1 ©2009Operating System Concepts

Synchronizácia procesov

Background Problém kritickej sekcie Petersonovo riešenie Synchronizačný hardvér Semafory Klasické problémy synchronizácie Monitory Synchronizačné príklady

6.2 ©2009Operating System Concepts

Ciele

Predstaviť problém kritickej sekcie, ktorej riešenia môžu byť použité na zabezpečenie konzistentnosti zdieľaných dát

Prezentovať ako hardvérové, tak aj softvérové riešenie problému kritickej sekcie

6.3 ©2009Operating System Concepts

Background

Súbežný (paralelný) prístup k zdieľaným dátam môže vyústiť do nekonzistentnosti dát

Zachovanie konzistentnosti dát vyžaduje mechanizmy ktoré zabezpečia usporiadané vykonávanie spolupracujúcich procesov

Predpokladajme riešenie problému konzument-producent Pridáme celočíselnú premennú counter (count), inicializovanú nulou. Na začiatku, counter je nastavený na 0. Jeho hodnotu zvyšuje producent zavedením vyprodukovanej položky do bufru a znižuje ju konzument.

6.4 ©2009Operating System Concepts

Producent

while (true) {

/* produkuj nejakú položku do nextProduced */

while (count == BUFFER_SIZE)

; // do nothing

buffer [in] = nextProduced;

in = (in + 1) % BUFFER_SIZE;

count++;

}

6.5 ©2009Operating System Concepts

Konzument

while (true) {

while (count == 0)

; // do nothing

nextConsumed = buffer[out];

out = (out + 1) % BUFFER_SIZE;

count--;

/* konzumuj položku v nextConsumed

}

6.6 ©2009Operating System Concepts

Súbežný výpočet

count++ môže byť implementovaný ako

register1 = count register1 = register1 + 1 count = register1

count– môže byť implementovaný ako

register2 = count register2 = register2 - 1 count = register2

Uvažujme nasledovné vykonanie, vychádzame z hodnoty counter “count = 5”

S0: producent vykoná register1 = count {register1 = 5}S1: producent vykoná register1 = register1 + 1 {register1 = 6} S2: konzument vykoná register2 = count {register2 = 5} S3: konzument vykoná register2 = register2 - 1 {register2 = 4} S4: producent vykoná count = register1 {count = 6 } S5: konzument vykoná count = register2 {count = 4}

6.7 ©2009Operating System Concepts

Riešenia problému kritickej sekcie

1. Vzájomné vylúčenie – Ak proces Pi sa vykonáva vo svojej kritickej sekcii, potom žiadne iné procesy nemôžu byť vykonávané vo svojich kritických sekciách

2. Pokrok – Ak žiaden proces nie je vykonávaný vo svojej kritickej sekcii a niektoré procesy chcú vstúpiť do svojej kritickej sekcie, potom iba tie procesy, ktoré sú vykonávané vo svojich vstupných sekciách sa môžu zúčastniť na rozhodovaní, ktorým vstúpia do svojej kritickej sekcie a tento výber nemôže byť odložený natrvalo

3. Ohraničené čakanie - Existuje hranica na čas čakania procesu, t.j.rozdiel času, kedy proces žiadal o vstúpenie do svojej kritickej sekcie a času, kedy bola povolená táto požiadavka

Predpokladajme že každý proces je vykonávaný nenulovou rýchlosťou

Relatívnu rýchlosť medzi N procesmi neuvažujeme

6.8 ©2009Operating System Concepts

Petersonovo riešenie

Riešenie 2 procesov Predpokladajme, že LOAD a STORE inštrukcie sú atomické; to

znamená, nemôžu byť prerušené. Dva procesy zdieľajú dve premenné:

int turn; Boolean flag[2]

Premenná turn indikuje ktoré (čie) turn vstupuje do kritickej sekcie The flag pole indikuje ak proces je pripravený vstúpiť do kritickej

sekcie. flag[i] = true implikuje že proces Pi je pripravený (ready)!

6.9 ©2009Operating System Concepts

do {

flag[i] = TRUE;

turn = j;

while (flag[j] && turn == j);

kritická sekcia

flag[i] = FALSE;

zvyšná sekcia

} while (TRUE);

Algoritmus pre Proces Pi

6.10 ©2009Operating System Concepts

Synchronizačný hardvér

Veľa systémov poskytuje hardvérovú podporu pre kód kritickej sekcie

Jednoprocesorové systémy – môžu zakázať prerušenia Práve bežiaci kód môže byť vykonaný bez prerušenia Všeobecne, toto riešenie je príliš neefektívne v

multiprocesorovom systéme Systémová výkonnosť klesá

Moderné stroje poskytujú špeciálnu atomickú hardvérovú inštrukciu – napr. „TestandSet“ inštrukcia

Atomický = neprerušiteľný Dovoľujú testovať a modifikovať obsah slova alebo vymeniť

obsahy 2 slov - atomicky Alebo „swap“ inštrukcia pracuje s obsahmi 2 slov

6.11 ©2009Operating System Concepts

TestAndSet Inštrukcia

Definícia:

boolean TestAndSet (boolean *target)

{

boolean rv = *target;

*target = TRUE;

return rv:

}

6.12 ©2009Operating System Concepts

Riešenie použitím TestAndSet

Zdieľaná booleovská premenná lock., inicializovaná na false. Riešenie:

do {

while ( TestAndSet (&lock ))

; // do nothing

// critical section

lock = FALSE;

// remainder section

} while (TRUE);

6.13 ©2009Operating System Concepts

Swap Inštrukcia

Definícia:

void Swap (boolean *a, boolean *b)

{

boolean temp = *a;

*a = *b;

*b = temp:

}

6.14 ©2009Operating System Concepts

Riešenie použitím Swap

Zdieľaná globálna ooleovská premenná lock inicializovaná na FALSE; Každý proces má lokálnu booleovskú premennú key

Riešenie:

do {

key = TRUE;

while ( key == TRUE)

Swap (&lock, &key );

// kritická sekcia

lock = FALSE;

// zvyšná sekcia

} while (TRUE);

6.15 ©2009Operating System Concepts

Ohraničené čakanie a vzájomné vylučovanie v TestandSet()

do {

waiting[i] = TRUE;

key = TRUE;

while (waiting[i] && key)

key = TestAndSet(&lock);

waiting[i] = FALSE;

// kritická sekcia

j = (i + 1) % n;

while ((j != i) && !waiting[j])

j = (j + 1) % n;

if (j == i)

lock = FALSE;

else

waiting[j] = FALSE;

// zvyšná sekcia

} while (TRUE);

6.16 ©2009Operating System Concepts

Semafory

Synchronizačný prostriedok nevyžaduje aktívne (zamestnané) čakanie Semafor S – integer premenná Semafor premenná prístupná cez 2 štandardné operácie S: wait() and signal()

Pôvodne nazývané P() a V() Menej komplikované Semafor môže byť prístupný len cez 2 štandardné atomické operácie

wait (S) {

while S <= 0

; // no-op

S--;

} signal (S) {

S++;

}

6.17 ©2009Operating System Concepts

Semafor ako všeobecný synchronizačný prostriedok

Počítací semafor – jeho integer hodnota môže mať neobmedzený rozsah

Binárny semafor – celočíselná hodnota, ktorá môže byť iba 0 alebo 1; môže byť jednoduchší z hľadiska implementácie

Tiež známy ako mutex locks

Je možné implementovať počítací semafor S ako binárny semafor

Poskytuje vzájomné vylučovanie (mutual exclusion)

Semaphore mutex; // initialized to 1

do {

wait (mutex);

// Kritická sekcia

signal (mutex);

// Zvyšná sekcia

} while (TRUE);

6.18 ©2009Operating System Concepts

Implementácia semaforu

Musí byť zabezpečené, že žiadne 2 procesy nemôžu vykonávať wait () a signal () na tom istom semafore v tom istom čase

Takto sa implementácia stáva problémom kritickej sekcie, kde wait a signal kód sú umiestnené v kritickej sekcii.

Implementácia zamestnaného čakania (busy waiting) v kritickej sekcii

Implementačný kód je krátky

Krátke aktívne čakanie ak kritická sekcia je zriedka zamestnaná

Poznamenajme, že ak aplikácie míňajú veľa času v kritickej sekcii, uvedené riešenie nie je dobré.

6.19 ©2009Operating System Concepts

Implementácia semafora bez aktívneho (zamestnaného) čakania

Ku každému semaforu je pripojený front čakajúcich. Každý semafor vo fronte čakajúcich má 2 dátové položky:

celočíselnú hodnotu

zoznam procesov (ukazovateľ na nasledujúci záznam v zozname)

Dve operácie:

block – umiestni proces, ktorý vyvolal operáciu do vhodného frontu čakajúcich.

wakeup – premiestni 1 z procesov z frontu čakajúcich a umiestni ho do frontu pripravených.

6.20 ©2009Operating System Concepts

Implementácia semafora bez aktívneho (zamestnaného) čakania

Implementácia „wait“:

wait(semaphore *S) {

S->value--;

if (S->value < 0) {

add this process to S->list;

block();

}

} Implementácia „signal“:

signal(semaphore *S) {

S->value++;

if (S->value <= 0) {

remove a process P from S->list;

wakeup(P);

}

}

6.21 ©2009Operating System Concepts

Uviaznutie a hladovanie

Uviaznutie (deadlock) – dva alebo viac procesov čakajú natrvalo na udalosť, ktorá môže byť zapríčinená iba jedným z čakajúcich procesov

Nech S a Q sú dva semafory inicializované na 1

P0 P1

wait (S); wait (Q);

wait (Q); wait (S);

. .

. .

. .

signal (S); signal (Q);

signal (Q); signal (S);

Hladovanie (starvation) – nekonečné blokovanie. Proces čaká natrvalo vo vnútri semaforu

Zmena priority - Plánovací problem kedy proces nižšej priority drží zámok potrebný pre proces vyššej priority

6.22 ©2009Operating System Concepts

Klasické problémy synchronizácie

Problém ohraničený zásobník

Problém čitatelia - zapisovatelia

Problém obedujúci filozofovia

6.23 ©2009Operating System Concepts

Problém ohraničený zásobník

N zásobníkov, každý zásobník je schopný držať 1 položku

Semafor mutex je inicializovaný na hodnotu 1, poskytuje vzájomné vylučovanie pre prístup do sady zásobníkov

Semafor full je inicializovaný na hodnotu 0, počíta počet plných zásobníkov

Semafor empty je inicializovaný na hodnotu N, počíta počet prázdnych zásobníkov

6.24 ©2009Operating System Concepts

Problém ohraničený zásobník

Štruktúra procesu „producent“

do {

// produkuj nejakú položku do nextproduced

wait (empty);

wait (mutex);

// pridaj nextproduced do zásobníka

signal (mutex);

signal (full);

} while (TRUE);

6.25 ©2009Operating System Concepts

Problém ohraničeného zásobníka

Štruktúra procesu „konzument“

do {

wait (full);

wait (mutex);

// vyber (premiestni) položku zo zásobníka do nextconsumed

signal (mutex);

signal (empty);

// konzumuj položku v nextconsumed

} while (TRUE);

6.26 ©2009Operating System Concepts

Problém čitatelia-zapisovatelia

Množina dát (dátový objekt) je zdieľaný medzi viacerými súbežnými procesmi

Čitatelia – iba čítajú obsah zdieľaného objektu; nemôžu vykonávať žiadne úpravy, zmeny

Zapisovatelia – môžu aj čítať aj zapisovať

Problém – dovoliť viacerým čitateľom čítať v rovnakom čase. Iba jeden zapisovateľ môže mať prístup k zdieľaným dátam v danom čase.

Zdieľané dáta

Dátový objekt

Semafor mutex inicializovaný na 1

Semafor wrt inicializovaný na 1

Integer readcount inicializovaný na 0

6.27 ©2009Operating System Concepts

Problém čitatelia - zapisovatelia

Štruktúra procesu „zapisovateľ“

do {

wait (wrt) ;

// zápis je vykonaný

signal (wrt) ;

} while (TRUE);

6.28 ©2009Operating System Concepts

Problém čitatelia - zapisovatelia

Štruktúra procesu „čitateľ“

do {

wait (mutex) ;

readcount ++ ;

if (readcount == 1)

wait (wrt) ;

signal (mutex)

// čítanie je vykonané

wait (mutex) ;

readcount - - ;

if (readcount == 0)

signal (wrt) ;

signal (mutex) ;

} while (TRUE);

6.29 ©2009Operating System Concepts

Problém obedujúcich filozofov

Zdieľané dáta

Misa ryže (dátový objekt) Semafor palička [5] inicializovaný na 1

6.30 ©2009Operating System Concepts

Problém obedujúcich filozofov

Štruktúra filozofa i:

do {

wait ( palička[i] );

wait ( palička[ (i + 1) % 5] );

// jedenie

signal ( palička[i] );

signal (palička[ (i + 1) % 5] );

// myslenie

} while (TRUE);

6.31 ©2009Operating System Concepts

Problémy so semaformiKritické regióny

Nesprávne použitie operácií v semafore:

signal (mutex) …. wait (mutex)

wait (mutex) … wait (mutex)

Vynechanie wait (mutex) alebo signal (mutex) (alebo oboch)

6.32 ©2009Operating System Concepts

Monitory

Synchronizačná konštrukcia vyššej úrovne ktorá poskytuje pohodlný a efektívny mechanizmus pre synchronizáciu procesov, je to množina operátorov definovaných programátorom

Iba jeden proces v danom čase môže byť aktívny vo vnútri monitora, reprezentácia (syntax) monitora je nasledovná:

monitor monitor-meno

{

// deklarovanie zdieľaných premenných

procedure body P1 (…) { …. }

procedure body Pn (…) {……}

Inicializačný kód ( ….) { … }

}

}

6.33 ©2009Operating System Concepts

Schematický pohľad na Monitor

6.34 ©2009Operating System Concepts

Premenné typu Condition

condition x, y;

Jediné 2 operácie, ktoré môžu byť vyvolané na premennej typu „condition“ sú:

x.wait () – proces, ktorý spôsobí vyvolanie tejto operácie je pozastavený, až kým iný proces vyvolá x.signal () .

x.signal () – táto operácia obnoví presne 1 pozastavený proces vyvolaný x.wait ()

6.35 ©2009Operating System Concepts

Monitor s premennými typu Condition

6.36 ©2009Operating System Concepts

Riešenie pomocou obedujúcich filozofov

monitor dp

{

enum { MYSLIACI, HLADNÝ;JEDIACI) stav [5] ;

condition filozof [5];

void zober (int i) {

sta[i] = HLADNY;

test(i);

if (stav[i] != JEDIACI) filozof [i].wait;

}

void polož (int i) {

stav[i] = MYSLIACI;

// testuj laveho a pravého suseda

test((i + 4) % 5);

test((i + 1) % 5);

}

6.37 ©2009Operating System Concepts

Riešenie pomocou obedujúcich filozofov

void test (int i) {

if ( (stav[(i + 4) % 5] != JEDIACI) &&

(stav[i] == HLADNY) &&

(stav[(i + 1) % 5] != JEDIACI) ) {

stav[i] = JEDIACI ;

filozoff[i].signal () ;

}

}

initialization_code() {

for (int i = 0; i < 5; i++)

stav[i] = MYSLIACI;

}

}

6.38 ©2009Operating System Concepts

Riešenie pomocou obedujúcich filozofov

Distribúcia paličiek je riadená monitorom dp, ktorého definícia je ukázaná v predošlom. Každý Filozof i vyvolá operácie zober()

a polož() v nasledujúcej postupnosti:

dp.zober (i);

JEDENIE

dp.polož (i);

6.39 ©2009Operating System Concepts

Implementácia Monitoru použitím Semaforov

Premenné semaphore mutex; // (initially = 1)semaphore next; // (initially = 0)int next-count = 0;

Každá procedúra F bude premiestnená

wait(mutex); …

body of F;

…if (next_count > 0)

signal(next)else

signal(mutex);

Mutual exclusion vo vnútri monitora je zabezpečené.