40
2018 - 2019 Problema sectiunii critice Capitolul 2

Problema sectiunii criticesoftware.ucv.ro/~cbadica/scd/cap2.pdf2018 - 2019 • Problema sectiunii critice se rezolva printr-un mecansim de sincronizare. Acesta include secvente de

  • Upload
    others

  • View
    24

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Problema sectiunii criticesoftware.ucv.ro/~cbadica/scd/cap2.pdf2018 - 2019 • Problema sectiunii critice se rezolva printr-un mecansim de sincronizare. Acesta include secvente de

2018 - 2019

Problema sectiunii critice

Capitolul 2

Page 2: Problema sectiunii criticesoftware.ucv.ro/~cbadica/scd/cap2.pdf2018 - 2019 • Problema sectiunii critice se rezolva printr-un mecansim de sincronizare. Acesta include secvente de

2018 - 2019

Rezumat

• Mecanisme de sincronizare pentru sectiunea critica.

Analiza unor algoritmi de baza.

• Implementarea mecansimelor de sincronizare in

Promela si Java.

Page 3: Problema sectiunii criticesoftware.ucv.ro/~cbadica/scd/cap2.pdf2018 - 2019 • Problema sectiunii critice se rezolva printr-un mecansim de sincronizare. Acesta include secvente de

2018 - 2019

Definirea problemei sectiunii critice

• Se considera N 2 procese care executa fiecare cate o

bucla infinita. Corpul buclei cuprinde:

– (i) sectiunea critica

– (ii) sectiunea non-critica.

• Cerintele de corectitudine: ce inseamna “sectiune

critica”?

• Cerinta de eficienta: este accesul la sectiunea critica

eficient?

• Presupuneri: referitoare la sectiunile critica si non-

critica.

Page 4: Problema sectiunii criticesoftware.ucv.ro/~cbadica/scd/cap2.pdf2018 - 2019 • Problema sectiunii critice se rezolva printr-un mecansim de sincronizare. Acesta include secvente de

2018 - 2019

Vizualizarea problemei sectiunii critice

Page 5: Problema sectiunii criticesoftware.ucv.ro/~cbadica/scd/cap2.pdf2018 - 2019 • Problema sectiunii critice se rezolva printr-un mecansim de sincronizare. Acesta include secvente de

2018 - 2019

Cerinte de corectitudine

• Excludere mutuala. Instructiunile din sectiunile critice

a doua sau mai multe procese nu pot fi intretesute.

• Lipsa interblocaj (engl. deadlock). Daca anumite

procese incearca sa intre in sectiunea lor critica atunci

eventual unul dintre ele va reusi.

• Lipsa infometare individuala (engl. starvation). Orice

proces care incearca sa intre in sectiunea sa critica

eventual va reusi.

• Observatie: Lipsa infometarii individuale lipsa

interblocajului

Page 6: Problema sectiunii criticesoftware.ucv.ro/~cbadica/scd/cap2.pdf2018 - 2019 • Problema sectiunii critice se rezolva printr-un mecansim de sincronizare. Acesta include secvente de

2018 - 2019

Cerinte de eficienta

• Accesul la sectiunea critica trebuie sa consume

cat mai putine resurse:

– timp de executie

– memorie

Page 7: Problema sectiunii criticesoftware.ucv.ro/~cbadica/scd/cap2.pdf2018 - 2019 • Problema sectiunii critice se rezolva printr-un mecansim de sincronizare. Acesta include secvente de

2018 - 2019

Presupuneri

• Progres in sectiunea critica. Daca un proces intra

in sectiunea critica, el va iesi din ea

• Non-progres in sectiunea non-critica. Daca un

proces este in sectiunea non-critica el se poate

termina sau se poate bucla la infinit.

Page 8: Problema sectiunii criticesoftware.ucv.ro/~cbadica/scd/cap2.pdf2018 - 2019 • Problema sectiunii critice se rezolva printr-un mecansim de sincronizare. Acesta include secvente de

2018 - 2019

• Problema sectiunii critice se rezolva printr-un mecansim de sincronizare. Acesta include secvente de instructiuni inainte si dupa sectiunea critica:

– Pre-protocol

– Post-protocol

Algoritm generic pentru problema sectiunii critice

variabile globale

p q

variabile locale

loop forever

sectiune non-critica

pre-protocol

sectiune critica

post-protocol

variabile locale

loop forever

sectiune non-critica

pre-protocol

sectiune critica

post-protocol

Algoritm generic

Sursa: M.Ben-Ari, 2006

Page 9: Problema sectiunii criticesoftware.ucv.ro/~cbadica/scd/cap2.pdf2018 - 2019 • Problema sectiunii critice se rezolva printr-un mecansim de sincronizare. Acesta include secvente de

2018 - 2019

• await conditie este o instructiune de asteptare conditionala. Daca conditie este falsa atunci executia procesului ce o contine se blocheaza pana cand conditie devine adevarata, prin actiunea altui proces. Altfel executia procesului ce o contine continua.

Sectiune critica V1

integer turn 1

p q

loop forever

p1: sectiune non-critica

p2: await turn = 1

p3: sectiune critica

p4: turn 2

loop forever

q1: sectiune non-critica

q2: await turn = 2

q3: sectiune critica

q4: turn 1

Prima incercare

Sursa: M.Ben-Ari, 2006

Page 10: Problema sectiunii criticesoftware.ucv.ro/~cbadica/scd/cap2.pdf2018 - 2019 • Problema sectiunii critice se rezolva printr-un mecansim de sincronizare. Acesta include secvente de

2018 - 2019

Diagrama de stari

• Urmatorul pas al unui algoritm concurent este

determinat de starea curenta a calculului, ce cuprinde:

– valorile pointerilor de control

– valorile variabilelor globale si locale ale fiecarui proces

• Pentru algoritmul “Sectiune critica V1” starea curenta

este reprezentata prin tripletul:

⟨𝑝𝑐𝑝, 𝑝𝑐𝑞 , 𝑡𝑢𝑟𝑛⟩

Page 11: Problema sectiunii criticesoftware.ucv.ro/~cbadica/scd/cap2.pdf2018 - 2019 • Problema sectiunii critice se rezolva printr-un mecansim de sincronizare. Acesta include secvente de

2018 - 2019

Numarul de stari

• Daca algoritmul contine 𝑁 procese, fiecare proces i are ni

instructiuni, exista 𝑀 variabile si fiecare variabila 𝑗 are 𝑚𝑗

valori posibile atunci numarul maxim de stari posibile este:

𝑛1 × 𝑛2 ×⋯× 𝑛𝑁 ×𝑚1 ×𝑚2 ×⋯×𝑚𝑀

• Pentru algoritmul nostru acest numar este 4 × 4 × 2 = 32 stari

posibile din care numai 16 pot fi atinse din starea initiala

⟨𝑝1, 𝑞1,1⟩.

• Numarul de stari se poate reduce la 4 daca se renunta la

instructiunile din sectiunea critica si non-critica, pe baza

observatiei ca p1 si p3 se pot inlocui cu comentarii, p1 este

totuna cu p2, iar p3 este totuna cu p4.

Page 12: Problema sectiunii criticesoftware.ucv.ro/~cbadica/scd/cap2.pdf2018 - 2019 • Problema sectiunii critice se rezolva printr-un mecansim de sincronizare. Acesta include secvente de

2018 - 2019

Vizualizarea diagramelor de stari

Sursa: M.Ben-Ari, 2006

Page 13: Problema sectiunii criticesoftware.ucv.ro/~cbadica/scd/cap2.pdf2018 - 2019 • Problema sectiunii critice se rezolva printr-un mecansim de sincronizare. Acesta include secvente de

2018 - 2019

Excluderea mutuala in prima incercare

• Rezulta din diagrama de stari simplificata observand ca starile

p2,q2,1 si p2,q2,2 nu sunt posibile.

• Cu alte cuvinte toate starile de forma p2,q2,turn sunt imposibile

pentru orice valoare posibila a variabilei turn.

Page 14: Problema sectiunii criticesoftware.ucv.ro/~cbadica/scd/cap2.pdf2018 - 2019 • Problema sectiunii critice se rezolva printr-un mecansim de sincronizare. Acesta include secvente de

2018 - 2019

Lipsa interblocajului in prima incercare

• Pe diagrama simplificata, fiind simetrica, analizam doar starile din stanga:

– Din starea p1,q1,2, q va intra in sectiunea critica

– Din starea p1,q2,2, q fiind in sectiunea critica, va progresa (conform ipotezei de

progres in sectiunea critica) in starea p1,q1,1, de unde p va intra in sectiunea critica.

Page 15: Problema sectiunii criticesoftware.ucv.ro/~cbadica/scd/cap2.pdf2018 - 2019 • Problema sectiunii critice se rezolva printr-un mecansim de sincronizare. Acesta include secvente de

2018 - 2019

Lipsa infometarii

• Lipsa infometarii se analizeaza pe diagrama initiala. Sa presupunem ca algoritmul se afla in starea p2,q1,2. p doreste sa intre in sectiunea critica, iar q se afla in sectiunea non-critica. Conform presupunerii de non-progres in sectiunea non-critica, turn nu va putea deveni 1, astfel ca p este infometat.

Sursa: M.Ben-Ari, 2006

Page 16: Problema sectiunii criticesoftware.ucv.ro/~cbadica/scd/cap2.pdf2018 - 2019 • Problema sectiunii critice se rezolva printr-un mecansim de sincronizare. Acesta include secvente de

2018 - 2019

Sectiune critica V2

boolean wantp false

boolean wantq false

p q

loop forever

p1: sectiune non-critica

p2: await wantq = false

p3: wantp true

p4: sectiune critica

p5: wantp false

loop forever

q1: sectiune non-critica

q2: await wantp = false

q3: wantq true

q4: sectiune critica

q5: wantq false

A doua incercare

Sursa: M.Ben-Ari, 2006

𝑤𝑎𝑛𝑡𝑝 ↔ p doreste sa intre in sectiunea critica

Page 17: Problema sectiunii criticesoftware.ucv.ro/~cbadica/scd/cap2.pdf2018 - 2019 • Problema sectiunii critice se rezolva printr-un mecansim de sincronizare. Acesta include secvente de

2018 - 2019

A doua incercare incalca excluderea mutuala

• 4 = p2, 11 = q2, 5 = p3, 12 = q3, 6 = p5, 13 = q5.

• Starea este pcp,pcq,wantp,wantq

• Se obtine secventa de stari 4,11,0,0 4,12,0,0 5,12,0,0 5,13,0,1 6,13,1,1 unde wantp = wantq = true.

Page 18: Problema sectiunii criticesoftware.ucv.ro/~cbadica/scd/cap2.pdf2018 - 2019 • Problema sectiunii critice se rezolva printr-un mecansim de sincronizare. Acesta include secvente de

2018 - 2019

Sectiune critica V3

boolean wantp false

boolean wantq false

p q

loop forever

p1: sectiune non-critica

p2: wantp true

p3: await wantq = false

p4: sectiune critica

p5: wantp false

loop forever

q1: sectiune non-critica

q2: wantq true

q3: await wantp = false

q4: sectiune critica

q5: wantq false

A treia incercare

Sursa: M.Ben-Ari, 2006 • Tema: Sa se arate ca acest algoritm:

– Verifica proprietatea de excludere mutuala

– Incalca proprietatea de interblocare

Page 19: Problema sectiunii criticesoftware.ucv.ro/~cbadica/scd/cap2.pdf2018 - 2019 • Problema sectiunii critice se rezolva printr-un mecansim de sincronizare. Acesta include secvente de

2018 - 2019

Sectiune critica V4

boolean wantp false

boolean wantq false

p q

loop forever

p1: sectiune non-critica

p2: wantp true

p3: while wantq = true

p4: wantp false

p5 wantp true

p6: sectiune critica

p7: wantp false

loop forever

q1: sectiune non-critica

q2: wantq true

q3: while wantp = true

q4: wantq false

q5 wantq true

q6: sectiune critica

q7: wantq false

A patra incercare

Sursa: M.Ben-Ari, 2006 • Tema: Sa se arate ca acest algoritm:

– Verifica proprietatea de excludere mutuala

– Nu verifica proprietatea de interblocare. Apare insa livelock = se executa instructiuni dar nu exista progres in sensul de a se intra in sectiunea critica

– Incalca proprietatea de infometare.

Page 20: Problema sectiunii criticesoftware.ucv.ro/~cbadica/scd/cap2.pdf2018 - 2019 • Problema sectiunii critice se rezolva printr-un mecansim de sincronizare. Acesta include secvente de

2018 - 2019

Algoritmul lui Dekker

boolean wantp false

boolean wantq false

interger turn 1

p q

loop forever

p1: sectiune non-critica

p2: wantp true

p3: while wantq = true

p4: if turn = 2

p5: wantp false

p6: await turn = 1

p7: wantp true

p8: sectiune critica

p9: turn 2

p10: wantp false

loop forever

q1: sectiune non-critica

q2: wantq true

q3: while wantp = true

q4: if turn = 1

q5: wantq false

q6: await turn = 2

q7: wantq true

q8: sectiune critica

q9: turn 1

q10: wantq false

Algoritmul lui Decker

Sursa: M.Ben-Ari, 2006

Page 21: Problema sectiunii criticesoftware.ucv.ro/~cbadica/scd/cap2.pdf2018 - 2019 • Problema sectiunii critice se rezolva printr-un mecansim de sincronizare. Acesta include secvente de

2018 - 2019

Corectitudinea algoritmului lui Dekker

• Observatie: dreptul de a insista sa intre in

sectiunea critica este controlat prin variabila

turn.

• Tema: Sa se arate ca algoritmul lui Dekker:

– Verifica proprietatea de excludere mutuala

– Verifica proprietatea de interblocare

– Verifica proprietatea de infometare

Page 22: Problema sectiunii criticesoftware.ucv.ro/~cbadica/scd/cap2.pdf2018 - 2019 • Problema sectiunii critice se rezolva printr-un mecansim de sincronizare. Acesta include secvente de

2018 - 2019

Instructiuni atomice complexe

• Este dificil de rezolvat problema sectiunii critice folosind doar instructiuni atomice de incarcare si stocare din/in memorie (engl. load and store).

• Instructiunea atomica test-and-set incarca valoarea unei variabile booleene common si apoi o seteaza la valoarea “true”.

test-and-set(common, local) is:

local common

common true

• Alt exemplu de instructiune atomica este exchange:

exchange(common, local) is:

integer temp

temp common

common local

local temp

Realizeaza citirea valorii common

si in acelasi timp setarea ei la valoarea

local intr-o secventa atomica.

Page 23: Problema sectiunii criticesoftware.ucv.ro/~cbadica/scd/cap2.pdf2018 - 2019 • Problema sectiunii critice se rezolva printr-un mecansim de sincronizare. Acesta include secvente de

2018 - 2019

Sectiune critica cu test-and-set

boolean common false

p q

integer localp

loop forever

p1: sectiune non-critica

repeat

p2: test-and-set(common,localp)

p3: until localp = false

p4: sectiune critica

p5: common false

integer localq

loop forever

q1: sectiune non-critica

repeat

q2: test-and-set(common,localq)

q3: until localq = false

q4: sectiune critica

q5: common false

Sectiune critica cu test-and-set

Sursa: M.Ben-Ari, 2006

• Tema: Sa se arate ca acest algoritm verifica toate cerintele de

corectitudine ale problemei sectiunii critice.

Page 24: Problema sectiunii criticesoftware.ucv.ro/~cbadica/scd/cap2.pdf2018 - 2019 • Problema sectiunii critice se rezolva printr-un mecansim de sincronizare. Acesta include secvente de

2018 - 2019

Sectiune critica cu exchange

boolean common true

p q

integer localp = false

loop forever

p1: sectiune non-critica

repeat

p2: exchange(common,localp)

p3: until localp = true

p4: sectiune critica

p5: exchange(common, localp)

integer localq = false

loop forever

q1: sectiune non-critica

repeat

q2: exchange(common,localq)

q3: until localq = true

q4: sectiune critica

q5: exchange(common, localq)

Sectiune critica cu exchange

Sursa: M.Ben-Ari, 2006

• Tema: Sa se arate ca acest algoritm verifica toate cerintele de

corectitudine ale problemei sectiunii critice.

Page 25: Problema sectiunii criticesoftware.ucv.ro/~cbadica/scd/cap2.pdf2018 - 2019 • Problema sectiunii critice se rezolva printr-un mecansim de sincronizare. Acesta include secvente de

2018 - 2019

Alte instructiuni atomice complexe

fetch-and-add(common, local, x) is:

local common

common common + x

compare-and-swap(common, old, new) is:

integer temp

temp common

if common = old

common new

return temp

• Tema: Sa se rezolve problema sectiunii critice folosind separat instructiunile atomice fetch-and-add si compare-and-swap.

Page 26: Problema sectiunii criticesoftware.ucv.ro/~cbadica/scd/cap2.pdf2018 - 2019 • Problema sectiunii critice se rezolva printr-un mecansim de sincronizare. Acesta include secvente de

2018 - 2019

Instructiuni atomice in Promela

• Toate intructiunile in Promela sunt atomice. Daca se doreste simularea efectului generarii de cod, trebuie transpus in Promela exact codul rezultat in urma compilarii.

• Daca se doreste ca o secventa de instructiuni sa fie considerata atomica (de exemplu pentru implementarea instructiunilor de tip test-and-set) se va folosi instructiunea atomic.

bit common = 0;

inline test-and-set (local) {

atomic {

local = common;

common = 1

}

}

• Tema: Sa se implementeze sectiunea critica in Promela folosind instructiuni atomice complexe.

Page 27: Problema sectiunii criticesoftware.ucv.ro/~cbadica/scd/cap2.pdf2018 - 2019 • Problema sectiunii critice se rezolva printr-un mecansim de sincronizare. Acesta include secvente de

2018 - 2019

Interfata Lock in Java

• Un mecansim de sincronizare se poate implementa folosind

interfata java.util.concurrent.locks.Lock in Java.

public interface Lock {

public void lock(); // before entering critical section

public void unlock(); // before leaving critical section

}

• Metoda lock reprezinta codul care se executa inainte de a intra

in sectiunea critica.

• Metoda unlock reprezinta codul care se executa dupa iesirea din

sectiunea critica.

Page 28: Problema sectiunii criticesoftware.ucv.ro/~cbadica/scd/cap2.pdf2018 - 2019 • Problema sectiunii critice se rezolva printr-un mecansim de sincronizare. Acesta include secvente de

2018 - 2019

Folosirea interfetei Lock

• Pentru sincronizare se defineste un obiect ce implementeaza interfata Lock.

public class Counter {

private long value = 0;

private Lock mutex = new LockImplementation();

public long getAndIncrement() {

long temp;

mutex.lock(); // enter critical section

try {

temp = value; // in critical section

value = temp + 1; // in critical section

} finally {

mutex.unlock(); // leave critical section

}

return temp;

}

}

• Metoda lock reprezinta codul care se executa inainte de a intra in sectiunea critica.

• Metoda unlock reprezinta codul care se executa dupa iesirea din sectiunea critica.

Aceasta clasa implementeaza algoritmi

pentru sectiunea critica.

Page 29: Problema sectiunii criticesoftware.ucv.ro/~cbadica/scd/cap2.pdf2018 - 2019 • Problema sectiunii critice se rezolva printr-un mecansim de sincronizare. Acesta include secvente de

2018 - 2019

Algoritmul lui Dekker in Java import java.util.concurrent.locks.Lock;

public class LockDekker implements Lock {

private volatile boolean[] want = {false, false};

private volatile int turn = 0;

public void lock() {

int i = ThreadID.get();

int j = 1-i;

want[i] = true;

while (want[j]) {

if (turn == j) {

want[i] = false;

while (turn != i) {}

want[i] = true;

}

}

}

public void unlock() {

int i = ThreadID.get();

turn = 1-i;

want[i] = false;

}

Se foloseste clasa ThreadID din Herlihy

& Shavit, 2008, 2012

Variabile volatile

Page 30: Problema sectiunii criticesoftware.ucv.ro/~cbadica/scd/cap2.pdf2018 - 2019 • Problema sectiunii critice se rezolva printr-un mecansim de sincronizare. Acesta include secvente de

2018 - 2019

Program de test public class LockTest {

final static int THREADS = 2;

final static int COUNT = 1024;

final static int PER_THREAD = COUNT / THREADS;

final static Thread[] thread = new Thread[THREADS];

static Counter c = new Counter();

public static void main(String[] args) {

ThreadID.reset();

for (int i = 0; i < THREADS; i++) { thread[i] = new CounterThread();}

for (int i = 0; i < THREADS; i++) { thread[i].start();}

for (int i = 0; i < THREADS; i++) {

try { thread[i].join(); }

catch(InterruptedException e) {}

}

System.out.println("Counter is: "+c.getValue());

}

}

class CounterThread extends Thread {

public void run() {

for (int i = 0; i < LockTest.PER_THREAD; i++) {

LockTest.c.getAndIncrement();

}

}

}

Page 31: Problema sectiunii criticesoftware.ucv.ro/~cbadica/scd/cap2.pdf2018 - 2019 • Problema sectiunii critice se rezolva printr-un mecansim de sincronizare. Acesta include secvente de

2018 - 2019

Variabile locale in fire - I

• Firele pot defini variabile locale private cu domeniu de acces

firul respectiv (engl. thread scope). Acest domeniu se numeste

si domeniul local de acces al firului – Thread Local Scope.

• Orice fir poate defini unul sau mai multe obiecte in TLS, iar

aceste obiecte sunt atat locale, cat si globale pentru firul

respectiv care le poate accesa.

– Globale – pot fi accesate de oriunde din cadrul firului respectiv. De

exemplu, daca un fir apeleaza o metoda dintr-un obiect, apelul metodei

va putea accesa variabilele TLS.

– Locale – fiecare fir va avea acces numai la propriile variable locale

TLS, variabilele TLS din alte fire fiind inaccesibile

Page 32: Problema sectiunii criticesoftware.ucv.ro/~cbadica/scd/cap2.pdf2018 - 2019 • Problema sectiunii critice se rezolva printr-un mecansim de sincronizare. Acesta include secvente de

2018 - 2019

Variabile locale in fire - II public class ThreadLocal<T> {

protected T initialValue( );

public T get( );

public void set(T value);

public void remove( );

}

• Metoda initialValue se suprascrie pentru a returna valoarea de intializare a

obiectului.

• Citirea valorii obiectului se face cu get. Daca obiectul nu a fost creat, el

este creat si initializat apeland initialValue. Daca valoarea curenta este

stearsa cu remove, o citire ulterioara cu get reapeleaza metoda initialValue

pentru initializare.

• Rescrierea valorii obiectului se face cu set, aceasta metoda nefiind

necesara in majoritatea cazurilor.

• Obiectele TLS se declara in general cu static, fiind astfel partajate de toate

firele. Cand se apeleaza metoda get, mecanismul intern al clasei

ThreadLocal asigura returnarea obiectului asignat unui fir specific.

Page 33: Problema sectiunii criticesoftware.ucv.ro/~cbadica/scd/cap2.pdf2018 - 2019 • Problema sectiunii critice se rezolva printr-un mecansim de sincronizare. Acesta include secvente de

2018 - 2019

Clasa ThreadID

public class ThreadID {

private static volatile int nextID = 0;

private static ThreadLocalID threadID = new ThreadLocalID();

public static int get() {

return threadID.get();

}

public static void reset() {

nextID = 0;

}

private static class ThreadLocalID

extends ThreadLocal<Integer> {

protected synchronized Integer initialValue() {

return nextID++;

}

}

}

Page 34: Problema sectiunii criticesoftware.ucv.ro/~cbadica/scd/cap2.pdf2018 - 2019 • Problema sectiunii critice se rezolva printr-un mecansim de sincronizare. Acesta include secvente de

2018 - 2019

Instructiuni atomice in Java

• Pachetul java.util.concurrent.atomic contine o multime de clase

utile pentru implementarea unor variabile cu acces atomic.

• Aceste clase dispun de metode get si set ce lucreaza similar cu

citirea respectiv scrierea variabilelor definite cu volatile. O

operatie set defineste o relatie de precedenta a executiei fata de

orice operatie ulterioara get asupra unei variabile.

• Spre exemplu, folosind clasa AtomicInteger se poate

implementa un contor cu acces atomic la operatiile de

incrementare / decrementare.

• Tema: Sa se reimplementeze programul prezentat anterior

pentru o multime de fire care realizeaza o operatie de numarare

concurenta, folosind clasa AtomicInteger.

Page 35: Problema sectiunii criticesoftware.ucv.ro/~cbadica/scd/cap2.pdf2018 - 2019 • Problema sectiunii critice se rezolva printr-un mecansim de sincronizare. Acesta include secvente de

2018 - 2019

Cuvantul cheie volatile in Java - I

• volatile in Java indica in principal faptul ca variabilele trebuie

stocate in memoria principala, nu in registre sau in memoria cache

pentru optimizarea codului.

• Incepand cu Java 5, volatile asigura mai multe garantii necesare

programarii concurente: – Garantia de asigurare a vizibilitatii actualizarii variabilelor partajate de

mai multe fire. Prin declararea unei variabile ca volatile se

garanteaza ca orice scriere a sa va fi realizata direct in memoria

principala, fiind corect vizibila din alte fire ce o citesc ulterior.

– Garantia unor relatii de precedenta intre instructiuni. • Daca firul 1 scrie o variabila volatile V, iar firul 2 citeste ulterior variabila V,

atunci toate variabilele vizibile in firul 1 inaintea scrierii variabilei V vor fi

vizibile in firul 2. Aceasta inseamna ca odata cu scrierea in memorie a lui V, se

scriu in memorie si celelalte variabile modificate de firul 1. • Instructiunile de acces la variabilele volatile nu sunt reordonate pentru

cresterea performantei executiei.

Page 36: Problema sectiunii criticesoftware.ucv.ro/~cbadica/scd/cap2.pdf2018 - 2019 • Problema sectiunii critice se rezolva printr-un mecansim de sincronizare. Acesta include secvente de

2018 - 2019

Cuvantul cheie volatile in Java - II

• Folosirea volatile nu este suficienta pentru folosirea /

accesarea variabilelor partajate de mai multe fire.

• volatile este suficient atunci cand valoarea scrisa de un fir

pentru o variabila este independenta de valoarea precedenta a

variabilei. Altfel, daca valoarea trebuie intai citita, iar valoarea

urmatoare determinata pe baza valorii citite, este necesara

folosirea sectiunilor critice pentru accesul concurent la variabila

din mai multe fire.

• Citirea si scrierea variabilelor volatile este mai costisitoare

decat citirea si scrierea variabilelor ne-volatile deoarece:

– variabilele volatile se citesc din si se scriu in memoria principala,

in timp ce variabilele ne-volatile se pot accesa din memoria cache.

– variabilele volatile previn reordonarea instructiunilor pentru

cresterea perfomantei.

Page 37: Problema sectiunii criticesoftware.ucv.ro/~cbadica/scd/cap2.pdf2018 - 2019 • Problema sectiunii critice se rezolva printr-un mecansim de sincronizare. Acesta include secvente de

2018 - 2019

Tema 1

• O sarcina (task sau job) cere determinarea daca un numar natural

𝑖 ∈ ℕ este prim. Considerand ca 𝑖 poate lua toate valorile din intervalul

[1, 𝑛], problema poate fi privita astfel: cum sa alocam cat mai eficient

executia celor n sarcini pe cele 𝑘 fire disponibile ?

• Variantele initiale, propuse ca tema in cursul trecut, sugereaza

folosirea unei prealocari (sau alocare statica) a sarcinilor pe firele

disponibile, astfel incat incarcarea firelor sa fie cat mai echilibrata.

• Se poate imagina o varianta de alocare dinamica, in sensul ca orice fir

liber (la inceputul executiei sau la terminarea executei sarcinii curente)

isi alege sarcina urmatoare disponibila. In acest fel este asigurat

echilibrul incarcarii tuturor firelor.

• Urmatoarea sarcina disponibila se poate reprezenta printr-un

numarator partajat (shared counter) de toate firele. Ori de cate ori este

preluata urmatoarea sarcina disponibila, numaratorul trebuie

incrementat. Accesul la numarator este o sectiune critica.

Page 38: Problema sectiunii criticesoftware.ucv.ro/~cbadica/scd/cap2.pdf2018 - 2019 • Problema sectiunii critice se rezolva printr-un mecansim de sincronizare. Acesta include secvente de

2018 - 2019

Tema 2

• Problema prizonierilor. Se considera o multime de 𝑝 prizonieri.

Directorul le ofera urmatoarea sansa: – Se permite prizonierilor sa se intalneasca toti o singura data, in prima zi

– In zilele urmatoare ei sunt inchisi in camere separate, un singur prizonier pe

camera

– Se considera o camera cu un comutator cu doua pozitii: aprins si stins

– Directorul selecteaza in fiecare zi cate un prizonier la intamplare si il duce in

camera cu comutatorul. Prizonierul poate actiona comutatorul schimbandu-i

pozitia sau il poate lasa neschimbat. Nimeni nu intra in camera comutatorului

in afara prizonierilor.

– Selectia prizonierilor este echitabila. Aceasta inseamna ca fiecare prizonier va

vizita eventual camera comutatorului de oricat de multe ori, in sensul ca nu

exista posibilitatea ca de la un moment dat incolo el sa fie ignorat de director.

– In orice moment un prizonier poate declara: “toti prizonierii au vizitat camera

comuntatorului”. Daca aceasta afirmatie este adevarata, prizonierii sunt

eliberati, altfel raman in inchisoare.

Page 39: Problema sectiunii criticesoftware.ucv.ro/~cbadica/scd/cap2.pdf2018 - 2019 • Problema sectiunii critice se rezolva printr-un mecansim de sincronizare. Acesta include secvente de

2018 - 2019

Tema 2 - II

a. Sa se propuna o strategie castigatoare a prizonierilor stiind ca

initial comutatorul este stins.

b. Sa se propuna o strategie castigatoare a prizonierilor nestiind

starea initiala a comutatorului.

c. Sa se implementeze un program Java care simuleaza alegerea

aleatoare a prizonierilor de catre director si trecerea lor prin

camera cu comutatorul. Camera se va implementa folosind

tehnica “sectiunii critice”, iar fiecare prizonier se va simula

printr-un fir separat ce acceseaza camera. In cadrul fiecarui fir

sa se implementeze strategia de rationament a prizonierilor si

sa se verifice corectitudinea strategiei prin executii multiple ale

simularii, in ambele situatii de la punctele a si b.

Page 40: Problema sectiunii criticesoftware.ucv.ro/~cbadica/scd/cap2.pdf2018 - 2019 • Problema sectiunii critice se rezolva printr-un mecansim de sincronizare. Acesta include secvente de

2018 - 2019

Tema 3

• Algoritmul lui Petereson.

Sursa: M.Ben-Ari, 2006 - Modelare si analiza in Promela

- Implementare in Java folosind interfata Lock